Search code examples
amazon-cognitoaws-amplifynextjs14

Next JS - getting the base localhost url to use in client side


I'm using Cognito in my Next JS (v14.0.3) app. To integrate, I utilized aws-amplify library. Following is my aws configuration file

... 

const awsConfig: ResourcesConfig = {
  Auth: {
    Cognito: {
      userPoolId: NEXT_PUBLIC_USER_POOL_ID,
      userPoolClientId: NEXT_PUBLIC_CLIENT_ID,
      loginWith: {
        oauth: {
          domain: NEXT_PUBLIC_COGNITO_DOMAIN,
          scopes: ['openid', 'email', 'profile'],
          redirectSignIn: [BASE_URL],
          redirectSignOut: [BASE_URL],
          responseType: 'code',
        },
      },
    },
  },
};

export default awsConfig;

I need my BASE_URL to be http://localhost:3000 when I'm in dev mode, while https://my-prod-site.com when in prod mode. How should I do it?

I tried this

const BASE_URL =
  process.env.NODE_ENV === 'development'
    ? 'http://localhost:' + process.env.PORT
    : process.env.HOST_URL;

It works on the server side, BASE_URL is getting set to http://localhost:3000. But this export file is used in the client side, so I'm guessing process.env.PORT is rendered undefined, since PORT is not prefixed by NEXT_PUBLIC_. Is updating my environment variables with a NEXT_PUBLIC_ prefixed value my only way?


Solution

  • Here's a suggestion to set up BASE_URL

    const BASE_URL = process.env.NODE_ENV === 'production' ?
      process.env.PRODUCTION_BASE_URL : (
        typeof window !== 'undefined' ?
          window.location.origin : 'http://localhost:' + process.env.PORT
      )
    

    I'm assuming you can gather your production url https://my-prod-site.com from an environment variable. To match the aforementioned code sample, you can add the following line to your environment variable file (.env / .env.local / .env.preview / .env.test / vercel environment configuration dashboard - whichever is applicable) -

    PRODUCTION_BASE_URL=https://my-prod-site.com
    

    You have to remember that Next JS will go through this file twice, once during server side rendering and one in the client side.

    • When you're in production, it will now use https://my-prod-site.com always
    • When in dev
      • During server side rendering, there will be no window variable. It will use process.env.PORT to dynamically set your value. (Btw, just check if PORT is returning undefined, sometimes it might do that, usually when system is relying on default 3000 port value)
      • During client side rendering, it will fetch your origin url dynamically using window.location.origin.