javascriptnext.jsnext-auth

TypeError [ERR_INVALID_URL]: Invalid URL using Next-auth only in Production


The app fails on trying to sign in using next-auth in my Next.js app in production mode when using the following command in the terminal on my local machine:

`yarn build && yarn start`

The error message observed in the terminal is as follows:

TypeError [ERR_INVALID_URL]: Invalid URL
    at new NodeError (node:internal/errors:372:5)
    at URL.onParseError (node:internal/url:553:9)
    at new URL (node:internal/url:629:5)
    at Object.redirect (/Users/name/Documents/GitHub/app/node_modules/next-auth/core/lib/default-callbacks.js:16:65)
    at createCallbackUrl (/Users/name/Documents/GitHub/app/node_modules/next-auth/core/lib/callback-url.js:20:35)
    at init (/Users/name/Documents/GitHub/app/node_modules/next-auth/core/init.js:132:48)
    at AuthHandlerInternal (/Users/name/Documents/GitHub/app/node_modules/next-auth/core/index.js:98:28)
    at AuthHandler (/Users/name/Documents/GitHub/app/node_modules/next-auth/core/index.js:335:34)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async NextAuthHandler (/Users/name/Documents/GitHub/app/node_modules/next-auth/next/index.js:38:20) {
  input: 'undefined/home',
  code: 'ERR_INVALID_URL'
}

If I run in development mode with the following command in the terminal, the issue does not occur:

`yarn dev`

This is my [...nextauth].ts file:

import NextAuth from "next-auth";
import type { NextAuthOptions } from "next-auth";

import GoogleProvider from "next-auth/providers/google";
import FacebookProvider from "next-auth/providers/facebook";
import EmailProvider from "next-auth/providers/email";

import { PrismaAdapter } from "@next-auth/prisma-adapter";
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

export const authOptions: NextAuthOptions = {
  adapter: PrismaAdapter(prisma),
  providers: [
    GoogleProvider({
      // @ts-ignore
      clientId: process.env.GOOGLE_CLIENT_ID,
      // @ts-ignore
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
    FacebookProvider({
      // @ts-ignore
      clientId: process.env.FACEBOOK_CLIENT_ID,
      // @ts-ignore
      clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
    }),
    EmailProvider({
      server: {
        host: process.env.SMTP_HOST,
        port: Number(process.env.SMTP_PORT),
        auth: {
          user: process.env.SMTP_USER,
          pass: process.env.SMTP_PASSWORD,
        },
      },
      from: process.env.SMTP_FROM,
    }),
  ],

  secret: process.env.NEXTAUTH_SECRET,

  callbacks: {
    session: async ({ session, token }) => {
      if (session?.user) {
        // @ts-ignore
        session.user.id = token.uid;
      }
      return session;
    },
    jwt: async ({ user, token }) => {
      if (user) {
        token.uid = user.id;
      }
      return token;
    },
  },
  session: {
    strategy: "jwt",

    maxAge: 30 * 24 * 60 * 60, // 30 days

    // updateAge: 24 * 60 * 60, // 24 hours
  },

  jwt: {
    secret: process.env.NEXTAUTH_SECRET,
  },
};

export default NextAuth(authOptions);

I tried figuring out what is different in production regarding the error message TypeError [ERR_INVALID_URL]: Invalid URL but could not figure it out. I haven't changed any environmental variables, and I have set the following variables in .env.local:

NEXTAUTH_SECRET="SomeLongString"
NEXTAUTH_URL="http://localhost:3000"

Adding package.json on request:

{
  "name": "app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@headlessui/react": "^1.7.4",
    "@heroicons/react": "^2.0.13",
    "@next-auth/prisma-adapter": "^1.0.5",
    "@prisma/client": "^4.7.1",
    "@tailwindcss/aspect-ratio": "^0.4.2",
    "@tailwindcss/typography": "^0.5.8",
    "@types/node": "18.11.9",
    "@types/react": "18.0.25",
    "@types/react-datepicker": "^4.8.0",
    "@types/react-dom": "18.0.9",
    "autoprefixer": "^10.4.13",
    "classnames": "^2.3.2",
    "clsx": "^1.2.1",
    "date-fns": "^2.29.3",
    "eslint": "8.28.0",
    "eslint-config-next": "13.0.4",
    "framer-motion": "^7.6.7",
    "graphql-request": "^5.0.0",
    "next": "13.0.4",
    "next-auth": "^4.18.6",
    "next-seo": "^5.14.1",
    "nodemailer": "^6.8.0",
    "postcss": "^8.4.19",
    "react": "18.2.0",
    "react-datepicker": "^4.8.0",
    "react-dom": "18.2.0",
    "react-hook-form": "^7.40.0",
    "react-hot-toast": "^2.4.0",
    "react-icons": "^4.6.0",
    "sass": "^1.56.1",
    "swr": "^1.3.0",
    "tailwindcss": "^3.2.4",
    "typescript": "4.9.3"
  },
  "devDependencies": {
    "prettier-plugin-prisma": "^4.4.0",
    "prisma": "^4.7.1"
  }
}

What am I missing?


Solution

  • I think it's because you're using the development link NEXTAUTH_URL="http://localhost:3000" in production. Instead, use the live link NEXTAUTH_URL="yourwebsite.com" in production.

    Also, instead of doing an if-statement to check whether you're in development or in production, have 2 .env files - one locally with the localhost url, and the one on live with the live url. This can help you better diagnose issues.

    More so, check to confirm that your env variables are actually accessible in your app.