I have been having a little issue for a while concerning dynamic routes in Next.JS.
After seeing a few tutorials an reading some documentation, I have the feeling that what I experiment is not what I should expect. I hope this post will help me by bringing a different look from someone with more experience.
Here is a detailed explanation of how I build a trial app, in the terminal, to reproduce my issue and at the end what I get vs what I expect:
% npx create-next-app@latest
✔ What is your project named? … mytrialapp
✔ Would you like to use TypeScript with this project? … No / Yes
✔ Would you like to use ESLint with this project? … No / Yes
✔ Would you like to use Tailwind CSS with this project? … No / Yes
✔ Would you like to use `src/` directory with this project? … No / Yes
✔ Use App Router (recommended)? … No / Yes
✔ Would you like to customize the default import alias? … No / Yes
Creating a new Next.js app in /Users/me/Documents/FireBase/mytrialapp.
Using npm.
Initializing project with template: app-tw
Installing dependencies:
- react
- react-dom
- next
- typescript
- @types/react
- @types/node
- @types/react-dom
- tailwindcss
- postcss
- autoprefixer
- eslint
- eslint-config-next
added 352 packages, and audited 353 packages in 19s
136 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Initialized a git repository.
Success! Created mytrialapp at /Users/me/Documents/FireBase/mytrialapp
% cd mytrialapp
At this point I edit the file next.config.js to make it look like this:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
distDir: 'the_public_area',
experimental: {
appDir: true,
},
images: {
unoptimized: true
}
}
module.exports = nextConfig
And I edit the file app/page.tsx to make it look like this:
import Image from 'next/image'
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<h1>The home page !!</h1>
</main>
)
}
I create two directories:
% mkdir app/members
and inside it I create one named [memberID], then inside it I create a file named page.tsx looking like this:
type Params = {
params: {
memberID: string
}
}
export default async function DynamicPage({ params: {memberID}}: Params) {
return (
<h1>The Dynamic Page !! ({memberID})</h1>
)
}
I then run the following commands in the terminal:
% npm install firebase
% firebase init hosting
######## #### ######## ######## ######## ### ###### ########
## ## ## ## ## ## ## ## ## ## ##
###### ## ######## ###### ######## ######### ###### ######
## ## ## ## ## ## ## ## ## ## ##
## #### ## ## ######## ######## ## ## ###### ########
ou're about to initialize a Firebase project in this directory:
/Users/me/Documents/FireBase/mytrialapp
== Project Setup
irst, let's associate this project directory with a Firebase project.
ou can create multiple project aliases by running firebase use --add,
ut for now we'll just set up a default project.
Please select an option: Use an existing project
Select a default Firebase project for this directory: myfbproject-7s3e8 (NisHal)
Using project myfbproject-7s3e8 (NisHal)
== Hosting Setup
our public directory is the folder (relative to your project directory) that
ill contain Hosting assets to be uploaded with firebase deploy. If you
ave a build process for your assets, use your build's output directory.
What do you want to use as your public directory? the_public_area
Configure as a single-page app (rewrite all urls to /index.html)? No
Set up automatic builds and deploys with GitHub? No
✔ Wrote the_public_area/404.html
✔ Wrote the_public_area/index.html
Writing configuration info to firebase.json...
Writing project information to .firebaserc...
✔ Firebase initialization complete!
I edit the firebase.json file to make it look like this:
{
"hosting": {
"public": "the_public_area",
"site": "mytrialapp",
"cleanUrls": true,
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
At this point everything is ready to try out the app, first in development mode:
After running:
% npm run dev
I use the web browser to look at: http://localhost:3000/
As expected I see displayed:
The home page !!
Then I look at: http://localhost:3000/members/Walt-Disney
Again as expected I see displayed:
The Dynamic Page !! (Walt-Disney)
Then I go and try in production mode, starting by running the two following commands in the terminal:
% npm run build % firebase deploy --only hosting
Then I use the web browser to see: https://mytrialapp.web.app/
As expected I see displayed:
The home page !!
Then I look at: https://mytrialapp.web.app/members/Walt-Disney
But here I see displayed:
404 | This page could not be found.
While I expected to see:
The Dynamic Page !! (Walt-Disney)
Can someone spot any problem in what I did while building the app above and explain why I do not get what I expect in production mode ?