9

Using next.js app deployed on firebase.

I have deployed the app already and using some time.

  1. I created a dynamic route page
  2. Deployed again app
  3. I could access the dynamic page via a router, but once I refresh the page I got a 404 page not found

Solutions that I tried and didn't work:

  • Rewrites with dynamicLink true
  • Rewrites with destination to the dynamic route and regex / source
"rewrites": [
      {
        "source": "/job/**",
        "destination": "/job/[jobId]/index.html"
      }
  • cleanUrls true
  • trailingSlash: true plus rewrite config with destination to the dynamic page
  • Any many more

I found a ton of solutions for this problem but no one didn't work for me.

Any idea?

firebase.json file:

{
  "hosting": {
    "public": "out",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "cleanUrls": true,
    "rewrites": [
      {
        "source": "**",
        "destination": "out/index.html"
      }
    ]
  },
  "functions": [
    {
      "source": "functions",
      "codebase": "default",
      "ignore": [
        "node_modules",
        ".git",
        "firebase-debug.log",
        "firebase-debug.*.log"
      ],
      "predeploy": ["npm --prefix \"$RESOURCE_DIR\" run build"]
    }
  ]
}

Mayank Kumar Chaudhari
  • 16,027
  • 10
  • 55
  • 122
Mark James
  • 338
  • 4
  • 15
  • 43

3 Answers3

3

For dynamic routes to work, you have to use server functions. You can use experimental frameworks feature by Firebase.

Checkout - https://firebase.google.com/docs/hosting/nextjs

Next.js advanced (dynamic) routing does not work without server functions.

Follow these steps:

  1. Delete your existing Firebase files and folders such as firebase.json and .firebase etc. And update firebase cli.
  2. Enable the web frameworks preview: firebase experiments:enable webframeworks
  3. Run firebase init hosting in the root directory of your Next.js app and follow the prompts.
  4. Run firebase deploy

Make sure you have paid plan activated so that functions can be creted by firebase-cli.

Option 2: working example

Try following

  1. rewrite all routes to index page
"rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  1. add following code to your index route
...
const router = useRouter();

useEffect(()=>{
    if(location.pathname !== "/")
        router.push(location.pathname)
}, [])
...

Checkout this repo for working example - working example Try navigating to https://byte-ceps.web.app/aboutOrAnything

Improving UX

// pages/index.jsx
import { useRouter } from "next/router";
import styles from "@/styles/Home.module.css";
import { useEffect } from "react";

export default function () {
  const router = useRouter();

  useEffect(() => {
    if (location.pathname === "/") router.push("/home");
    else router.push(location.pathname);
  }, []);

// you can create custom loading animation / splash screen here
  return (
    <div>
      <main className={styles.main}>
        <h1> Loading... </h1>
      </main>
    </div>
  );
}

move your landing page to /home

Option 3:

Deploy on vercel.com Simply create a vercel account and link it to your GitHub. Create project, select your GitHub repo and setup any secrets if you need to. You are done.

If you want to have your .web.app domain, you need to either redirect to vercel deployment from your firebase site or use iframe. But if you have already purchased your own domain name, you can simply setup cname entry and your deployment is ready.

Update

Also in your firebase.json shared in question, rewrite should be to /index.html and not out/index.html

Mayank Kumar Chaudhari
  • 16,027
  • 10
  • 55
  • 122
  • Thanks for the great answer, unfortunately, the first two options didn't solve the issue. And third is not an option that I have. – Mark James Feb 03 '23 at 00:59
  • Added a working example repo for the option 2 – Mayank Kumar Chaudhari Feb 03 '23 at 03:06
  • Option 2 works, but there is that gap when the home page is loading and then switches to the current page. This is not the right solution it's a workaround, so If I don't get a better solution in the next 2,3 days I will accept your solution. Thanks for your answers! – Mark James Feb 03 '23 at 23:24
  • Please check the repo. There is an elegant solution for that. Rename your `pages/index.jsx` to `pages/home.jsx` and put your routing `useEffect` and a splash screen in the index.jsx – Mayank Kumar Chaudhari Feb 04 '23 at 17:59
  • @MayankKumarChaudhari still not working. first two option is not working and third option is not option in my case also. – Rajendra A Verma Feb 15 '23 at 13:34
  • I have similar type of [question](https://stackoverflow.com/questions/75459091/dynamic-routes-in-app-dir-in-nextjs13-not-working-after-deploying-to-firebase-ho) – Rajendra A Verma Feb 15 '23 at 13:36
0

This firebase.json works for me.

{
      "hosting": {
        "public": "out",
        "ignore": [
          "firebase.json",
          "**/.*",
          "**/node_modules/**"
        ],
        "rewrites": [
          {
            "source": "**",
            "destination": "/index.html"
          }
        ]
      }
    }
  • it's not working on my side, with this, redirects me to the index page every time after refresh, it's better than 404, but it's not the solution. – Mark James Jan 30 '23 at 22:49
0

To properly handle dynamic routes in Firebase hosting, you need to set cleanUrls: false in your firebase.json file and add a rewrite rule to handle all requests to index.html:

The following will handle dynamic request correctly, however if you refresh it will take you to to the home page.

"cleanUrls": false,
"rewrites": [
  {
    "source": "**",
    "destination": "/index.html"
  }
]

You can fix this issue by adding a static directory rule to your firebase.json file:

"staticDirectory": [
      {
        "source": "/_next/static",
        "destination": "/_next/static"
      }
    ]

Full code:

 // firebase.json
{
  "hosting": {
    "public": "out",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "cleanUrls": false,
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    "staticDirectory": [
      {
        "source": "/_next/static",
        "destination": "/_next/static"
      }
    ]
  },
}
kingkong.js
  • 659
  • 4
  • 14