Next.js 11如何根据hostname重写根路径首页内容?
问题根因
- 根路径rewrite失效:Next.js 路由匹配优先级中,预渲染的静态页面(你用
getStaticProps生成的/pages/index.js)优先级远高于rewrites规则,所以请求根路径时直接返回了预生成的静态首页,根本不会触发rewrite逻辑,非首页路径没有对应预渲染静态页,所以rewrite能正常生效。 - 自定义server缓存问题:默认情况下Next.js会把
getStaticProps生成的静态页做全局缓存,你直接调用handle(req,res)时会优先返回缓存的静态首页,不会触发你写的hostname判断逻辑,只有缓存过期触发revalidate时才会更新内容,所以出现首次加载不对、刷新才对的问题。
可行解决方案(适配Next 11.1.2版本)
方案1:调整静态页路径 + 带域名匹配的rewrite(推荐,改动最小,保留静态缓存能力)
把原首页/pages/index.js重命名为/pages/home.js,让根路径没有预渲染的静态页,即可正常触发rewrite规则,同时通过has字段匹配hostname实现多域名映射:
// next.config.js rewrites配置 async rewrites() { return [ // 匹配子域名根路径重定向到mission页 { source: '/', has: [ { type: 'host', value: 'mission.mydomain.com', }, ], destination: '/mission', }, // 其他域名根路径重定向到原来的首页 { source: '/', destination: '/home', }, // 保留原有其他rewrite规则 { source: '/foo', destination: '/contact', }, ] }
这个方案无需改动原有页面的getStaticProps和revalidate逻辑,两个页面的缓存完全独立,不会互相干扰。
方案2:优化自定义server逻辑,跳过根路径静态缓存
如果不想修改现有页面路径,可以调整自定义server的根路径处理逻辑,强制根路径走服务端渲染逻辑,不走全局静态缓存:
// server.js server.get('/', async function(req,res){ if (req.hostname === 'mission.mydomain.com') { return app.render(req, res, '/mission', req.query) } // 强制渲染/index页,不走静态文件缓存 return app.render(req, res, '/index', req.query) }); // 其他路由走默认处理逻辑 server.all('*', (req, res) => { return handle(req, res) })
这个方案可以保留原有/pages/index.js的所有配置,仅修改server逻辑即可生效。
方案3:首页改用getServerSideProps,直接判断域名渲染不同内容
如果不需要严格保留静态生成能力,直接把原首页的getStaticProps改成getServerSideProps,在服务端判断域名后返回对应内容和组件:
// /pages/index.js // 引入原有首页和mission页的组件 import HomePage from '../components/HomePage' import MissionPage from '../components/MissionPage' // 引入原有两个页面的getStaticProps逻辑 import { getStaticProps as getHomeProps } from './home' import { getStaticProps as getMissionProps } from './mission' export async function getServerSideProps(context) { const hostname = context.req.headers.host if (hostname === 'mission.mydomain.com') { const missionRes = await getMissionProps(context) return { props: { pageType: 'mission', ...missionRes.props } } } const homeRes = await getHomeProps(context) return { props: { pageType: 'home', ...homeRes.props } } } export default function Index(props) { if (props.pageType === 'mission') { return <MissionPage {...props} /> } return <HomePage {...props} /> }
你原本配置的2秒revalidate本身已经接近动态渲染的性能表现,改用getServerSideProps不会有明显的性能差异,同时无需修改配置文件和server逻辑。
内容的提问来源于stack exchange,提问作者Dauncing
相关产品推荐
相关产品推荐

