如何使非英语网址在 next.js 中工作?

How to make non-english urls to work in next.js?

如何使非英语网址与 next.js ssr/client 一起使用?欢迎任何想法、重写等。

前段时间重写有助于解决这个问题,但在一些更新后它停止工作。这是我尝试 fix this.

Codesandbox.

我什至尝试使用 Unicode 路径(重写),但它给了我奇怪的错误:

{
  source: encodeURI('/рус'),
  destination: "/u0440/u0443/u0441"
}

Error: Requested and resolved page mismatch: //u0440/u0443/u0441 /u0440/u0443/u0441

我已经实现了 "pretty url" 到真实页面之间的映射。

此实施没有什么好处。

  1. 漂亮的urls可以来自db
  2. pretty urls 可以在任何结构中(与目录结构无关)
  3. 漂亮 urls 可以是任何语言:](你可以控制你的 api returns 作为 url)
  4. 整个应用程序对他们来说是不可知的
  5. 允许您在一处操作所有 url(添加前缀或其他)

简而言之,我有一个简单的对象,如下所示:

const routes = {
  pageName: (prettyUrl) => ({href: 'path/to/page', as: prettyUrl});
}

客户端和服务器都在使用这个对象。

客户端

每个数据的 api returns url 属性 来自 db.

假设我们的应用显示了用户列表和一个用户,这意味着每个用户的 API return 非常 url(它可以是任何东西 必须是唯一的).

import { routes } from '../routes';
import NextLink from 'next/link';

export const userCard = ({ user }) => (
  <div>
    <NextLink {...routes.userPage(user.url)}>{user.name}</NextLink>
  </div>
);

服务器 我有一个 custom express server 从数据库加载映射(url -> pageName)。

const express = require('express');
const next = require('next');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(async () => {
  const urlsMap = await loadUrlsMap();
  const server = express();

  server.get('*', (req, res) => {
    if (urlMaps.hasOwnProperty(req.pathname)) {
      const page = urlMaps(req.pathname);
      const additionalData = {}; // can have query / params from req
      return app.render(req, res, page.href, { ...additionalData });
    }
    return handle(req, res);
  });

  server.listen(port, err => {
    if (err) throw err;
    console.log(`> Ready on http://localhost:${port}`);
  });
});

我已经展示了一个非常基本的实现,但认为您可以将任何东西(例如 userId)传递给 routes.pageName 方法,并且每个方法都可以用它执行任何逻辑并且 return { href, as }.

在我的实际实现中,我使用的是 path-to-regex,它允许我传递 url 模板和更多 :]

我可以用越南语文本完成此操作。诀窍是再添加 2 个重写:一个是真实文本,另一个是 urlencoded 文本。

{
  source: "/lo%C3%A0i/:slug",
  destination: "/species/:slug"
},
{
  source: "/loài/:slug",
  destination: "/species/:slug"
}

现在我在 next.config.js 中像这样重写:

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
})

const pathsToRewrite = [
  ['/пользователь/:id/:nickname', '/user/:id/:nickname'],
  ['тест', 'test'],
]
const rewrites = pathsToRewrite.map(([ru, eng]) => ({ source: encodeURI(ru), destination: eng }))

module.exports = withBundleAnalyzer({
  async rewrites() {
    return rewrites
  },
})