When refreshing a V0 app on a non-root route returns a 404, the issue is that the hosting platform does not know how to handle client-side routes. V0 generates Next.js App Router projects, which use file-based routing and should not have this problem — but it occurs when you export V0 code and deploy as a static site without proper SPA fallback configuration, or when dynamic routes lack generateStaticParams for static exports.
Why page refreshes cause 404 errors in exported V0 apps
V0 apps use Next.js App Router, which supports both server-side and static rendering. When deployed to Vercel via Share then Publish, routing works correctly because Vercel understands Next.js routing natively. However, when you export V0 code and deploy it elsewhere — or use output: 'export' for a static build — the server receives a request for /dashboard but has no corresponding HTML file at that path. Without a fallback rule, the server returns 404. This is different from general Vercel deployment route issues, which involve Next.js-specific configuration problems rather than SPA fallback rules.
- Static export (output: 'export' in next.config.js) without generating all route HTML files
- Dynamic routes like /blog/[slug] without generateStaticParams in static export mode
- Deploying to a non-Vercel host without SPA fallback configuration
- Incorrect basePath configuration causing all routes to 404 except the root
- Trailing slash mismatch between generated paths and server expectations
Error messages you might see
404: This page could not be found.The hosting platform received a request for a route (like /dashboard) but has no matching file. In static export mode, Next.js must generate an HTML file for every route at build time.
Error: Page "/blog/[slug]" is missing "generateStaticParams()" so it cannot be used with "output: export".When using static export, every dynamic route needs generateStaticParams to tell Next.js which paths to pre-render at build time.
we are reconfiguring our servers. don't worry, just refresh this page after a short while :)This is a generic server error page that appears when the hosting platform cannot find the requested route. It indicates the SPA fallback is not configured.
Before you start
- Exported V0 project deployed to a hosting platform
- Access to the hosting platform's configuration (Vercel, Netlify, or server config)
- Understanding of the difference between static export and server-side rendering
How to fix it
Deploy to Vercel using the native Next.js adapter instead of static export
Vercel understands Next.js routing natively. Static export strips away server-side routing capabilities, but Vercel's default adapter preserves them.
Deploy to Vercel using the native Next.js adapter instead of static export
Vercel understands Next.js routing natively. Static export strips away server-side routing capabilities, but Vercel's default adapter preserves them.
Remove output: 'export' from your next.config.js if it was added. Deploy to Vercel and the framework will handle routing automatically — both static pages and dynamic routes work without fallback configuration.
// next.config.js — static export causes 404 on refreshconst nextConfig = { output: 'export',};// next.config.js — let Vercel handle routing nativelyconst nextConfig = { // Remove output: 'export' for Vercel deployment};Expected result: All routes including dynamic ones work on page refresh without any 404 errors.
Add generateStaticParams for dynamic routes in static export mode
Static export requires knowing all possible routes at build time. Without generateStaticParams, Next.js cannot create HTML files for dynamic routes like /blog/[slug].
Add generateStaticParams for dynamic routes in static export mode
Static export requires knowing all possible routes at build time. Without generateStaticParams, Next.js cannot create HTML files for dynamic routes like /blog/[slug].
In each dynamic route's page.tsx file, export a generateStaticParams function that returns all valid parameter combinations. Next.js will pre-render an HTML file for each one during the build.
// app/blog/[slug]/page.tsx — fails in static exportexport default function BlogPost({ params,}: { params: { slug: string };}) { return <article>{params.slug}</article>;}// app/blog/[slug]/page.tsx — works in static exportexport async function generateStaticParams() { const posts = await fetch('https://api.example.com/posts') .then(res => res.json()); return posts.map((post: { slug: string }) => ({ slug: post.slug, }));}export default function BlogPost({ params,}: { params: { slug: string };}) { return <article>{params.slug}</article>;}Expected result: The build generates individual HTML files for each blog post, so /blog/my-post works on refresh.
Configure SPA fallback for non-Vercel hosts
If you deploy the static export to Netlify, Apache, or Nginx, the server needs a rule to serve index.html for all unmatched routes so client-side routing can take over.
Configure SPA fallback for non-Vercel hosts
If you deploy the static export to Netlify, Apache, or Nginx, the server needs a rule to serve index.html for all unmatched routes so client-side routing can take over.
Add platform-specific fallback configuration. For Netlify, create a _redirects file. For nginx, add a try_files directive. For Apache, add a .htaccess rewrite rule.
// No fallback configured — server returns 404 for /dashboard// Netlify: public/_redirects// /* /index.html 200// Nginx:// location / {// try_files $uri $uri.html $uri/ /index.html;// }// vercel.json (for custom Vercel config):// {// "rewrites": [// { "source": "/(.*)", "destination": "/index.html" }// ]// }Expected result: The server serves the app's HTML for any route, and Next.js client-side routing handles the correct page display.
Fix basePath and trailingSlash configuration
If your app is hosted at a subpath (like example.com/app/) or the server expects trailing slashes, mismatched configuration causes 404s on specific routes.
Fix basePath and trailingSlash configuration
If your app is hosted at a subpath (like example.com/app/) or the server expects trailing slashes, mismatched configuration causes 404s on specific routes.
Check next.config.js for basePath and trailingSlash settings. If deploying to a subpath, set basePath. If the hosting platform requires trailing slashes, enable trailingSlash.
// next.config.js — missing basePath for subpath deployconst nextConfig = {};// next.config.js — configured for subpath deploymentconst nextConfig = { basePath: '/app', trailingSlash: true,};Expected result: Routes like /app/dashboard resolve correctly with trailing slashes matching the server's expectations.
Complete code example
1/** @type {import('next').NextConfig} */2const nextConfig = {3 // For Vercel deployment: remove 'output: export'4 // For static hosting: uncomment the line below5 // output: 'export',67 // Set basePath if deploying to a subpath8 // basePath: '/my-app',910 // Enable trailing slashes if your host requires them11 // trailingSlash: true,1213 images: {14 // Required for static export — disable Image Optimization15 // unoptimized: true,16 },17};1819module.exports = nextConfig;Best practices to prevent this
- Deploy to Vercel whenever possible — it handles Next.js routing natively without any fallback configuration
- Avoid output: 'export' unless your hosting platform requires static files — it removes server-side capabilities
- Always add generateStaticParams to every dynamic route when using static export
- Test page refresh on every route after deploying, not just the home page
- Set trailingSlash consistently — mismatches between your config and hosting cause subtle 404s
- For complex deployments to non-Vercel platforms, consider RapidDev for deployment configuration assistance
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
My V0 Next.js app works on Vercel but I need to deploy it as a static export to Netlify. When I refresh any page other than the homepage, I get a 404 error. How do I configure SPA fallback and generateStaticParams for all my dynamic routes?
Frequently asked questions
Why does my V0 app work on the homepage but 404 on other routes after refresh?
The server only has an HTML file for the root path (/). When you navigate client-side, JavaScript handles routing. On refresh, the browser requests /dashboard directly from the server, which has no file for that path. Add SPA fallback rules or use Vercel's native Next.js deployment.
Do I need SPA fallback configuration on Vercel?
No. Vercel natively understands Next.js routing. SPA fallback rules are only needed when deploying static exports to other platforms like Netlify, Apache, or Nginx.
What is the difference between this and a general Vercel deployment routing issue?
This page covers SPA fallback configuration for static exports on any platform. Vercel-specific deployment issues — where routes work in V0 preview but break on Vercel — involve Next.js configuration problems like middleware conflicts or incorrect rewrites.
Can I create a custom 404 page for unmatched routes?
Yes. In Next.js App Router, create app/not-found.tsx. This component renders automatically when no route matches. You can also call the notFound() function from any page to trigger it programmatically.
How do I fix 404 errors on page refresh for dynamic routes?
If using static export (output: 'export'), add a generateStaticParams function to each dynamic route's page.tsx that returns all valid parameter values. If deploying to Vercel without static export, dynamic routes work automatically.
Does trailingSlash configuration affect 404 errors?
Yes. If your hosting platform expects trailing slashes (/dashboard/) but your Next.js config generates paths without them (/dashboard), the server returns a 404. Set trailingSlash: true in next.config.js to match your platform's requirements.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your issue.
Book a free consultation