I have a site that is statically exported, and has dynamic routes.
This site works fine in dev mode. However if I build & export it, and then serve the static files, it has an issue.
You can go to the site root and click on a link, which will take you to a dynamic post page like http://localhost:3000/post/1
and will work, but if you refresh the page (or visit directly) it 404s.
Why is this? Do dynamic routes, that need to access the router query object, not work when statically exported?
The dynamic route docs don't mention any caveats to dynamic routes when used with static export.
The code:
Taking the next.js static example to start with, I edited it’s pages/post/[id].tsx
by removing the getStaticPaths
and getStaticProps
(as I don’t require build time static generation) and added clientside fetching on mount. I’m grabbing the router.query.id value and using it to fetch data:
⚡ Codesandbox here (which works fine as its running in dev, not exported served files)
import Head from 'next/head'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
import { GetPost } from '../../lib/postdata_api'
import { PostData } from '../../types/postdata'
const Post = () => {
const [postData, setPostData] = useState<null | PostData>(null)
const router = useRouter()
const id = router.query.id as string
const fetchData = async () => setPostData(await GetPost(id))
useEffect(() => {
if (!router.isReady) return
fetchData()
}, [router, router.isReady])
if (!postData) return 'Loading...'
return (
<main>
<Head>
<title>{postData.title}</title>
</Head>
<h1>{postData.title}</h1>
<p>{postData.body}</p>
<Link href="/">
<a>Go back to home</a>
</Link>
</main>
)
}
export default Post
Expected Behavior
I expected it to behave the as it does it dev. Meaning a user can:
- click a link on the root page
- view the dynamic post page eg
/post/1
- refresh / directly visit this post (without it 404ing)
To Reproduce
- Download the code sandbox or github repo
- run
npm run export && serve out
- visit
http://localhost:3000
- click a link to a post
- press refresh to see the 404
I have a site that is statically exported, and has dynamic routes.
This site works fine in dev mode. However if I build & export it, and then serve the static files, it has an issue.
You can go to the site root and click on a link, which will take you to a dynamic post page like http://localhost:3000/post/1
and will work, but if you refresh the page (or visit directly) it 404s.
Why is this? Do dynamic routes, that need to access the router query object, not work when statically exported?
The dynamic route docs don't mention any caveats to dynamic routes when used with static export.
The code:
Taking the next.js static example to start with, I edited it’s pages/post/[id].tsx
by removing the getStaticPaths
and getStaticProps
(as I don’t require build time static generation) and added clientside fetching on mount. I’m grabbing the router.query.id value and using it to fetch data:
⚡ Codesandbox here (which works fine as its running in dev, not exported served files)
import Head from 'next/head'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
import { GetPost } from '../../lib/postdata_api'
import { PostData } from '../../types/postdata'
const Post = () => {
const [postData, setPostData] = useState<null | PostData>(null)
const router = useRouter()
const id = router.query.id as string
const fetchData = async () => setPostData(await GetPost(id))
useEffect(() => {
if (!router.isReady) return
fetchData()
}, [router, router.isReady])
if (!postData) return 'Loading...'
return (
<main>
<Head>
<title>{postData.title}</title>
</Head>
<h1>{postData.title}</h1>
<p>{postData.body}</p>
<Link href="/">
<a>Go back to home</a>
</Link>
</main>
)
}
export default Post
Expected Behavior
I expected it to behave the as it does it dev. Meaning a user can:
- click a link on the root page
- view the dynamic post page eg
/post/1
- refresh / directly visit this post (without it 404ing)
To Reproduce
- Download the code sandbox or github repo
- run
npm run export && serve out
- visit
http://localhost:3000
- click a link to a post
- press refresh to see the 404
- Could you plz try accessing the page with a trailing slash? – Irfanullah Jan Commented Aug 17, 2022 at 16:42
- @IrfanullahJan Good idea! but sadly that didn't change anything. – Ash Commented Aug 17, 2022 at 18:23
3 Answers
Reset to default 3TL;DR
Add the following configuration to next.config.js
and then make the export again:
// next.config.js
module.exports = {
trailingSlash: true,
}
Explanation
It's possible to fix this behavior changing manually all routes produced by the export process to folders and renaming each *.html
file to index.html
, as follows:
Produced route by next export
:
/posts/1.html
"Fixed" route:
/posts/1/index.html
So, if the page is refreshed when the browser has /posts/1
as url, the route will acquire a trailing slash and will bee /posts/1/
, the HTTP petition will be done correctly because the HTTP server picks up the file index.html
under any directory by default, and the static page will be shown.
Apparently, this behavior was the default prior Next.js v9
when export, and can be enabled again adding the following configuration to the file next.config.js
(in order to avoid doing the change per route manually):
// next.config.js
module.exports = {
trailingSlash: true,
}
I know it's a little late, but I found out this solution when I faced the same problem yesterday.
Source: official documentation
I see that you use 'serve' from Vercel. To have pretty URLs, you need to config rewrite for the server.
According to this instruction https://github./vercel/serve-handler#rewrites-array. You need to add this config to make it work with pretty URLs.
// public/serve.json
{
"rewrites": [
{ "source": "/post/*", "destination": "/post/[id].html" }
]
}
// next.config.js
const nextConfig = {
exportPathMap: () => {
return {
'/newpassword/index': { page: '/newpassword/[uuid]' }
};
},
}
run yarn build
, then the return in out/
will be: newpassword/[uuid]/index.html
to newpassword/index.html
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745110766a4611836.html
评论列表(0条)