Next.js basePath and redirects don't work on Netlify

We are having an issue with building Next.js pages with Netlify. When we are running the project locally, all the redirects are working and basePath is added correctly to all links and pages. However, on Netlify it doesn’t work for some reason.
Here is some info:

Deploy URL: https://deploy-preview-12--traveller-crossing.netlify.app/

Build command: npm run build
Publish directory: .next

next.config.js:

module.exports = {
  reactStrictMode: true,
  basePath: '/traveller-crossing',
  async redirects() {
    return [
      {
        source: '/',
        destination: '/traveller-crossing',
        permanent: true,
        basePath: false,
      },
    ];
  },
};

netlify.toml:

[build]
  publish = ".next"

[[plugins]]
  package = "@netlify/plugin-nextjs"

[[redirects]]
  from = "/"
  to = "/traveller-crossing"

Full build log:

3:42:20 PM: Build ready to start
3:42:22 PM: build-image version: 8925038cf853b22d6397cdcb9904ac88b66bb383 (focal)
3:42:22 PM: build-image tag: v4.5.0
3:42:22 PM: buildbot version: 17f45048b6251cf70bb32902eeaa66613a6ae7d1
3:42:22 PM: Fetching cached dependencies
3:42:22 PM: Starting to download cache of 596.0MB
3:42:25 PM: Finished downloading cache in 3.442541533s
3:42:25 PM: Starting to extract cache
3:42:42 PM: Finished extracting cache in 16.199766479s
3:42:42 PM: Finished fetching cache in 20.154434528s
3:42:42 PM: Starting to prepare the repo for build
3:42:43 PM: Preparing Git Reference pull/12/head
3:42:43 PM: Parsing package.json dependencies
3:42:44 PM: Starting build script
3:42:44 PM: Installing dependencies
3:42:44 PM: Python version set to 2.7
3:42:45 PM: Started restoring cached node version
3:42:47 PM: Finished restoring cached node version
3:42:47 PM: v16.13.1 is already installed.
3:42:48 PM: Now using node v16.13.1 (npm v8.1.2)
3:42:48 PM: Started restoring cached build plugins
3:42:48 PM: Finished restoring cached build plugins
3:42:48 PM: Attempting ruby version 2.7.2, read from environment
3:42:49 PM: Using ruby version 2.7.2
3:42:50 PM: Using PHP version 8.0
3:42:50 PM: Started restoring cached yarn cache
3:42:55 PM: Finished restoring cached yarn cache
3:42:55 PM: No yarn workspaces detected
3:42:55 PM: Started restoring cached node modules
3:42:55 PM: Finished restoring cached node modules
3:42:56 PM: Installing NPM modules using Yarn version 1.22.10
3:42:56 PM: yarn install v1.22.10
3:42:56 PM: warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
3:42:56 PM: [1/4] Resolving packages...
3:42:57 PM: success Already up-to-date.
3:42:57 PM: Done in 0.40s.
3:42:57 PM: NPM modules installed using Yarn
3:42:57 PM: Started restoring cached go cache
3:42:57 PM: Finished restoring cached go cache
3:42:57 PM: go version go1.16.5 linux/amd64
3:42:57 PM: go version go1.16.5 linux/amd64
3:42:57 PM: Installing missing commands
3:42:57 PM: Verify run directory
3:42:58 PM: ​
3:42:58 PM: ────────────────────────────────────────────────────────────────
3:42:58 PM:   Netlify Build                                                 
3:42:58 PM: ────────────────────────────────────────────────────────────────
3:42:58 PM: ​
3:42:58 PM: ❯ Version
3:42:58 PM:   @netlify/build 20.0.1
3:42:58 PM: ​
3:42:58 PM: ❯ Flags
3:42:58 PM:   baseRelDir: true
3:42:58 PM:   buildId: 61a8bf2ce19aed00082fd880
3:42:58 PM:   deployId: 61a8bf2ce19aed00082fd882
3:42:58 PM: ​
3:42:58 PM: ❯ Current directory
3:42:58 PM:   /opt/build/repo
3:42:58 PM: ​
3:42:58 PM: ❯ Config file
3:42:58 PM:   /opt/build/repo/netlify.toml
3:42:58 PM: ​
3:42:58 PM: ❯ Context
3:42:58 PM:   deploy-preview
3:42:59 PM: ​
3:42:59 PM: ❯ Loading plugins
3:42:59 PM:    - @netlify/plugin-nextjs@4.0.0-beta.11 from netlify.toml and package.json
3:42:59 PM: ​
3:42:59 PM: ────────────────────────────────────────────────────────────────
3:42:59 PM:   1. @netlify/plugin-nextjs (onPreBuild event)                  
3:42:59 PM: ────────────────────────────────────────────────────────────────
3:42:59 PM: ​
3:42:59 PM: Thank you for trying the Essential Next.js beta plugin. 
3:42:59 PM: Please share feedback (both good and bad) at https://ntl.fyi/next-beta-feedback
3:42:59 PM: Next.js cache restored.
3:42:59 PM: Netlify configuration property "build.environment.NEXT_PRIVATE_TARGET" value changed.
3:42:59 PM: ​
3:42:59 PM: (@netlify/plugin-nextjs onPreBuild completed in 376ms)
3:42:59 PM: ​
3:42:59 PM: ────────────────────────────────────────────────────────────────
3:42:59 PM:   2. Build command from Netlify app                             
3:42:59 PM: ────────────────────────────────────────────────────────────────
3:42:59 PM: ​
3:42:59 PM: $ npm run build
3:43:00 PM: > build
3:43:00 PM: > next build
3:43:01 PM: info  - Checking validity of types...
3:43:08 PM: info  - Creating an optimized production build...
3:43:18 PM: info  - Compiled successfully
3:43:18 PM: info  - Collecting page data...
3:43:22 PM: info  - Generating static pages (0/14)
3:43:22 PM: info  - Generating static pages (3/14)
3:43:22 PM: info  - Generating static pages (6/14)
3:43:22 PM: info  - Generating static pages (10/14)
3:43:23 PM: info  - Generating static pages (14/14)
3:43:23 PM: info  - Finalizing page optimization...
3:43:23 PM: Page                                                                 Size     First Load JS
3:43:23 PM: β”Œ ● / (400 ms)                                                       3.13 kB        80.3 kB
3:43:23 PM: β”œ   /_app                                                            0 B            71.3 kB
3:43:23 PM: β”œ ● /[slug]                                                          311 B          71.6 kB
3:43:23 PM: β”œ   β”œ /inspirations
3:43:23 PM: β”œ   β”” /offers
3:43:23 PM: β”œ β—‹ /404                                                             194 B          71.5 kB
3:43:23 PM: β”œ Ξ» /api/hello                                                       0 B            71.3 kB
3:43:23 PM: β”œ ● /inspiration/[continent] (1091 ms)                               2.08 kB        73.3 kB
3:43:23 PM: β”œ   β”œ /inspiration/south-america (583 ms)
3:43:23 PM: β”œ   β”” /inspiration/europa (508 ms)
3:43:23 PM: β”œ ● /inspiration/[continent]/[country] (459 ms)                      2.09 kB        73.3 kB
3:43:23 PM: β”œ   β”œ /inspiration/south-america/venezuela
3:43:23 PM: β”œ   β”” /inspiration/europa/germany
3:43:23 PM: β”œ ● /inspiration/[continent]/[country]/[offer] (330 ms)              409 B          71.7 kB
3:43:23 PM: β”œ   β”œ /inspiration/europa/germany/hiking-in-bavaria
3:43:23 PM: β”œ   β”” /inspiration/south-america/venezuela/12-days-in-the-caribbean
3:43:23 PM: β”œ β—‹ /login (483 ms)                                                  1.4 kB          107 kB
3:43:23 PM: β”œ β—‹ /setpassword (396 ms)                                            1.55 kB         107 kB
3:43:23 PM: β”” β—‹ /signup (471 ms)                                                 1.47 kB         107 kB
3:43:23 PM: + First Load JS shared by all                                        71.3 kB
3:43:23 PM:   β”œ chunks/framework-91d7f78b5b4003c8.js                             42 kB
3:43:23 PM:   β”œ chunks/main-63025e69d376ad29.js                                  27.8 kB
3:43:23 PM:   β”œ chunks/pages/_app-d9db60601a769715.js                            492 B
3:43:23 PM:   β”œ chunks/webpack-3292717d4a48fd85.js                               895 B
3:43:23 PM:   β”” css/4815fbd8797ecfe1.css                                         1.81 kB
3:43:23 PM: Ξ»  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
3:43:23 PM: β—‹  (Static)  automatically rendered as static HTML (uses no initial props)
3:43:23 PM: ●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)
3:43:23 PM: ​
3:43:23 PM: (build.command completed in 23.3s)
3:43:23 PM: ​
3:43:23 PM: ────────────────────────────────────────────────────────────────
3:43:23 PM:   3. @netlify/plugin-nextjs (onBuild event)                     
3:43:23 PM: ────────────────────────────────────────────────────────────────
3:43:23 PM: ​
3:43:23 PM: Moving static page files to serve from CDN...
3:43:23 PM: Moved 21 files
3:43:23 PM: Netlify configuration property "redirects" value changed to [
3:43:23 PM:   {
3:43:23 PM:     from: '/',
3:43:23 PM:     query: {},
3:43:23 PM:     to: '/traveller-crossing',
3:43:23 PM:     force: false,
3:43:23 PM:     conditions: {},
3:43:23 PM:     headers: {}
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/_next/image*',
3:43:23 PM:     query: { url: ':url', w: ':width', q: ':quality' },
3:43:23 PM:     to: '/traveller-crossing/_ipx/w_:width,q_:quality/:url',
3:43:23 PM:     status: 301
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/_ipx/*',
3:43:23 PM:     to: '/.netlify/builders/_ipx',
3:43:23 PM:     status: 200
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/_next/static/image/*',
3:43:23 PM:     to: '/static/image/:splat',
3:43:23 PM:     status: 200
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/cache/*',
3:43:23 PM:     to: '/404.html',
3:43:23 PM:     status: 404,
3:43:23 PM:     force: true
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/server/*',
3:43:23 PM:     to: '/404.html',
3:43:23 PM:     status: 404,
3:43:23 PM:     force: true
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/serverless/*',
3:43:23 PM:     to: '/404.html',
3:43:23 PM:     status: 404,
3:43:23 PM:     force: true
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/traces',
3:43:23 PM:     to: '/404.html',
3:43:23 PM:     status: 404,
3:43:23 PM:     force: true
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/routes-manifest.json',
3:43:23 PM:     to: '/404.html',
3:43:23 PM:     status: 404,
3:43:23 PM:     force: true
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/build-manifest.json',
3:43:23 PM:     to: '/404.html',
3:43:23 PM:     status: 404,
3:43:23 PM:     force: true
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/prerender-manifest.json',
3:43:23 PM:     to: '/404.html',
3:43:23 PM:     status: 404,
3:43:23 PM:     force: true
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/react-loadable-manifest.json',
3:43:23 PM:     to: '/404.html',
3:43:23 PM:     status: 404,
3:43:23 PM:     force: true
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/BUILD_ID',
3:43:23 PM:     to: '/404.html',
3:43:23 PM:     status: 404,
3:43:23 PM:     force: true
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/_next/static/*',
3:43:23 PM:     to: '/static/:splat',
3:43:23 PM:     status: 200
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/api',
3:43:23 PM:     to: '/.netlify/functions/___netlify-handler',
3:43:23 PM:     status: 200
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/api/*',
3:43:23 PM:     to: '/.netlify/functions/___netlify-handler',
3:43:23 PM:     status: 200
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/*',
3:43:23 PM:     to: '/.netlify/functions/___netlify-handler',
3:43:23 PM:     status: 200,
3:43:23 PM:     conditions: { Cookie: [Array] },
3:43:23 PM:     force: true
3:43:23 PM:   },
3:43:23 PM:   {
3:43:23 PM:     from: '/traveller-crossing/*',
3:43:23 PM:     to: '/.netlify/functions/___netlify-handler',
3:43:23 PM:     status: 200
3:43:23 PM:   }
3:43:23 PM: ].
3:43:23 PM: ​
3:43:23 PM: (@netlify/plugin-nextjs onBuild completed in 72ms)
3:43:23 PM: ​
3:43:23 PM: ────────────────────────────────────────────────────────────────
3:43:23 PM:   4. Functions bundling                                         
3:43:23 PM: ────────────────────────────────────────────────────────────────
3:43:23 PM: ​
3:43:23 PM: Packaging Functions from .netlify/functions-internal directory:
3:43:23 PM:  - ___netlify-handler/___netlify-handler.js
3:43:23 PM:  - ___netlify-odb-handler/___netlify-odb-handler.js
3:43:23 PM:  - _ipx/_ipx.js
3:43:23 PM: ​
3:43:52 PM: ​
3:43:52 PM: (Functions bundling completed in 29.5s)
3:43:52 PM: ​
3:43:52 PM: ────────────────────────────────────────────────────────────────
3:43:52 PM:   5. @netlify/plugin-nextjs (onPostBuild event)                 
3:43:52 PM: ────────────────────────────────────────────────────────────────
3:43:52 PM: ​
3:43:53 PM: Next.js cache saved.
3:43:53 PM: ​
3:43:53 PM: (@netlify/plugin-nextjs onPostBuild completed in 888ms)
3:43:53 PM: ​
3:43:53 PM: ────────────────────────────────────────────────────────────────
3:43:53 PM:   6. Deploy site                                                
3:43:53 PM: ────────────────────────────────────────────────────────────────
3:43:53 PM: ​
3:43:53 PM: Starting to deploy site from '.next'
3:43:53 PM: Creating deploy tree 
3:43:53 PM: Creating deploy upload records
3:43:54 PM: 30 new files to upload
3:43:54 PM: 2 new functions to upload
3:43:55 PM: Starting post processing
3:43:56 PM: Post processing - HTML
3:43:57 PM: Post processing - header rules
3:43:57 PM: Post processing - redirect rules
3:43:57 PM: Post processing done
3:43:57 PM: Site is live ✨
3:43:57 PM: Finished waiting for live deploy in 2.097063417s
3:43:57 PM: Site deploy was successfully initiated
3:43:57 PM: ​
3:43:57 PM: (Deploy site completed in 4s)
3:43:57 PM: ​
3:43:57 PM: ────────────────────────────────────────────────────────────────
3:43:57 PM:   7. @netlify/plugin-nextjs (onEnd event)                       
3:43:57 PM: ────────────────────────────────────────────────────────────────
3:43:57 PM: ​
3:43:57 PM: Thank you for trying the Essential Next.js beta plugin. 
3:43:57 PM: Please share feedback (both good and bad) at https://ntl.fyi/next-beta-feedback
3:43:57 PM: ​
3:43:57 PM: (@netlify/plugin-nextjs onEnd completed in 5ms)
3:43:58 PM: ​
3:43:58 PM: ────────────────────────────────────────────────────────────────
3:43:58 PM:   Netlify Build Complete                                        
3:43:58 PM: ────────────────────────────────────────────────────────────────
3:43:58 PM: ​
3:43:58 PM: (Netlify Build completed in 59.1s)
3:43:58 PM: Caching artifacts
3:43:58 PM: Started saving node modules
3:43:58 PM: Finished saving node modules
3:43:58 PM: Started saving build plugins
3:43:58 PM: Finished saving build plugins
3:43:58 PM: Started saving yarn cache
3:44:05 PM: Finished saving yarn cache
3:44:05 PM: Started saving pip cache
3:44:05 PM: Finished saving pip cache
3:44:05 PM: Started saving emacs cask dependencies
3:44:05 PM: Finished saving emacs cask dependencies
3:44:05 PM: Started saving maven dependencies
3:44:05 PM: Finished saving maven dependencies
3:44:05 PM: Started saving boot dependencies
3:44:05 PM: Finished saving boot dependencies
3:44:05 PM: Started saving rust rustup cache
3:44:05 PM: Finished saving rust rustup cache
3:44:05 PM: Started saving go dependencies
3:44:05 PM: Finished saving go dependencies
3:44:05 PM: Build script success
3:45:46 PM: Finished processing build request in 3m24.211096256s

The weird thing is that it used to work, but starting the latest deploy it does not with no changes to redirect logic. Any insights are appreciated.

Hey there,

Can you try using the most recent beta release, version 12? It is linked here: Conflict between firebase functions and netlify functions

Let us know if this helps!

Hey Hillary. We already are.
Here is the full package.json file:

{
  "name": "traveller-crossing",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "axios": "^0.24.0",
    "contentful": "^9.1.4",
    "formik": "^2.2.9",
    "next": "12.0.3",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "yup": "^0.32.11"
  },
  "devDependencies": {
    "@netlify/plugin-nextjs": "^4.0.0-beta.12",
    "@types/node": "16.11.6",
    "@types/react": "17.0.34",
    "@typescript-eslint/eslint-plugin": "^5.3.1",
    "autoprefixer": "^10.4.0",
    "eslint": "7",
    "eslint-config-next": "12.0.3",
    "eslint-config-prettier": "^8.3.0",
    "husky": "^7.0.4",
    "postcss": "^8.3.11",
    "prettier": "^2.4.1",
    "tailwindcss": "^2.2.19",
    "typescript": "4.4.4"
  }
}

Previously we were using version 7 and it was working there too, to be honest.

Thanks for following up! In your build log above it says:
Loading plugins 3:42:59 PM: - @netlify/plugin-nextjs@4.0.0-beta.11 from netlify.toml and package.json so I was going off of that. But you’re absolutely right, it does look like you’ve updated to version 12.

To confirm, when I load the deploy preview you linked above, I am getting redirected to traveller-crossing. This reads to me as what you were attempting to accomplish. Here is a screenshot of what I am seeing:

Is this different than the expected behaviour? If it is, can you elaborate in a different way what you are looking for support with?

Thanks for your patience!

Yeah, so let me go into more detail.
You will need to log in or sign up to be routed to the homepage (which should have the base path of /traveller-crossing).
You can use the following test credentials:
url: https://deploy-preview-12--traveller-crossing.netlify.app/traveller-crossing/login
login: netlifyforum@gmail.com
password: 12345678

Basically, we have 3 static pages that are not dynamically generated: /login, /setpassword, /signup
They work both locally and on netlify with no issues. And you were rerouted correctly to one, which proves that.

On the other hand we have pages that are built using getStaticPaths and getStaticProps that are fetched from Contentful. And those do not get prefixed with the base path. For example, once you log in, you will see the sidebar with links and links to different pages at the bottom of the page. All those pages are built the way I mentioned above. Links to those pages get prefixed with the base path, but when the pages are built on Netlify, the base path is getting ignored. That means the following:

The link to the page on deploy preview is: https://deploy-preview-12--traveller-crossing.netlify.app/traveller-crossing/inspirations . That is correct and is getting prefixed with the base path. Once you go to the page, it will throw a 404 error. The actual page is living under this path https://deploy-preview-12--traveller-crossing.netlify.app/inspirations . That is incorrect and the base path is ignored.

When you jump to the homepage, which lives under URL https://deploy-preview-12--traveller-crossing.netlify.app/ , you are not redirected to https://deploy-preview-12--traveller-crossing.netlify.app/traveller-crossing , which is not correct, because the redirect is set up in next.config.js and in netlify.toml

The pages directory looks like this:

On localhost everything described above works like a charm, but not on Netlify, which is why I wondering what I am missing on Netlify’s side.

Hope that clears things up.

quick update: we updated to version 13 of the beta plugin and it fixed the pages building

2 Likes

actually, it improved the situation, but didn’t fix it completely. Pages are being built inconsistently and error out when you add a redirect from an external website to that URL with masked domain (for example, when you redirect from https://domain.com/test-path to https://deploy-preview-12--traveller-crossing.netlify.app/test-path and the URL showing up stays as https://domain.com/test-path but shows content from https://deploy-preview-12--traveller-crossing.netlify.app/test-path

Hey there, @Justbigmack :wave:

Apologies for the delay here! I wanted to let you know that we have your Helpdesk ticket and will be continuing the conversation there. Stay tuned to your email. Thanks :slight_smile: