自定义服务端路由
Examples
- Basic custom server
- Express integration
- Hapi integration
- Koa integration
- Parameterized routing
- SSR caching
一般你使用next start
命令来启动 next 服务,你还可以编写代码来自定义路由,如使用路由正则等。
当使用自定义服务文件,如下面例子所示叫 server.js 时,确保你更新了 package.json 中的脚本。
- {
- "scripts": {
- "dev": "node server.js",
- "build": "next build",
- "start": "NODE_ENV=production node server.js"
- }
- }
下面这个例子使 /a
路由解析为./pages/b
,以及/b
路由解析为./pages/a
;
- // This file doesn't go through babel or webpack transformation.
- // Make sure the syntax and sources this file requires are compatible with the current node version you are running
- // See https://github.com/zeit/next.js/issues/1245 for discussions on Universal Webpack or universal Babel
- const { createServer } = require('http')
- const { parse } = require('url')
- const next = require('next')
- const dev = process.env.NODE_ENV !== 'production'
- const app = next({ dev })
- const handle = app.getRequestHandler()
- app.prepare().then(() => {
- createServer((req, res) => {
- // Be sure to pass `true` as the second argument to `url.parse`.
- // This tells it to parse the query portion of the URL.
- const parsedUrl = parse(req.url, true)
- const { pathname, query } = parsedUrl
- if (pathname === '/a') {
- app.render(req, res, '/b', query)
- } else if (pathname === '/b') {
- app.render(req, res, '/a', query)
- } else {
- handle(req, res, parsedUrl)
- }
- }).listen(3000, err => {
- if (err) throw err
- console.log('> Ready on http://localhost:3000')
- })
- })
next
的 API 如下所示
next(opts: object)
opts 的属性如下:dev (boolean) 判断 Next.js 应用是否在开发环境 - 默认false
- dir (string) Next 项目路径 - 默认'.'
- quiet (boolean) 是否隐藏包含服务端消息在内的错误信息 - 默认false
- conf (object) 与next.config.js的对象相同 - 默认{}
生产环境的话,可以更改 package.json 里的start
脚本为NODE_ENV=production node server.js
。
禁止文件路由
默认情况,Next
将会把/pages
下的所有文件匹配路由(如/pages/some-file.js
渲染为 site.com/some-file
)
如果你的项目使用自定义路由,那么有可能不同的路由会得到相同的内容,可以优化 SEO 和用户体验。
禁止路由链接到/pages
下的文件,只需设置next.config.js
文件如下所示:
- // next.config.js
- module.exports = {
- useFileSystemPublicRoutes: false
- }
注意useFileSystemPublicRoutes
只禁止服务端的文件路由;但是客户端的还是禁止不了。
你如果想配置客户端路由不能跳转文件路由,可以参考Intercepting popstate
。
动态前缀
有时你需要设置动态前缀,可以在请求时设置assetPrefix
改变前缀。
使用方法如下:
- const next = require('next')
- const micro = require('micro')
- const dev = process.env.NODE_ENV !== 'production'
- const app = next({ dev })
- const handleNextRequests = app.getRequestHandler()
- app.prepare().then(() => {
- const server = micro((req, res) => {
- // Add assetPrefix support based on the hostname
- if (req.headers.host === 'my-app.com') {
- app.setAssetPrefix('http://cdn.com/myapp')
- } else {
- app.setAssetPrefix('')
- }
- handleNextRequests(req, res)
- })
- server.listen(port, (err) => {
- if (err) {
- throw err
- }
- console.log(`> Ready on http://localhost:${port}`)
- })
- })