当前位置:   article > 正文

Next实现国际化,接口反向代理,冲突了_next-intl

next-intl

最近在写next的项目,用到了国际化,使用了 react-i18next 但是感觉很费劲,配置起来很麻烦,所以换了一种方式,那就是:next-intl

发现还不错,后来要做接口,发现跨域,然后增加反向代理,则两者出现了冲突

国际化

第一步,需要安装

npm install next-intl
  • 1

第二步,配置

import createNextIntlPlugin from 'next-intl/plugin';
const withNextIntl = createNextIntlPlugin();

/** @type {import('next').NextConfig} */
const nextConfig = {};
export default withNextIntl(nextConfig)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

src 目录下创建 i18n-config.ts i18n.ts middleware.ts 文件 与 messages 目录

export const i18n = {
    defaultLocale: "en",
    locales: ["en", "zh"],
} as const;
export const locales = i18n.locales;
export const defaultLocale = i18n.defaultLocale;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
import { notFound } from "next/navigation";
import { getRequestConfig } from 'next-intl/server';
import { locales } from '@/i18n-config'

export default getRequestConfig(async ({ locale }: any) => {
    if (!locales.includes(locale)) notFound();

    console.log(locale)
    return {
        messages: (await import(`./messages/${locale}.json`)).default
    };
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
import createMiddleware from 'next-intl/middleware';
import { locales, defaultLocale } from '@/i18n-config';

export default createMiddleware({
    locales,
    defaultLocale,
    // 默认语言不重定向
    localePrefix: 'as-needed'
});

export const config = {
    matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述

messages目录结构

{
    "head": {
        "Login":"Login"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5

项目结构:

在这里插入图片描述

要把以前写的页面 放到 [locale] 中,这样路由则会走 /语言/index

第三步:使用

服务端:

import {useTranslations} from 'next-intl';
export default function Page() {
  const t = useTranslations('Head');
  return (
    <div className="note--empty-state">
      <span className="note-text--empty-state">
        {t('login')}
      </span>
    </div>
  )
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
import {getTranslations} from 'next-intl/server';

export default async function Page() {
  const t = await getTranslations('Head');
  return (
    <div className="note--empty-state">
      <span className="note-text--empty-state">
        {t('initText')}
      </span>
    </div>
  )
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

客户端:

import {useTranslations} from 'next-intl';
export default function Sidebar() {
  const t = useTranslations('Head');
  return (
    <>
      <section className="col sidebar">
        <section className="sidebar-menu" role="menubar">
          <SidebarSearchField search={t('search')} />
          <EditButton noteId={null}>{t('new')}</EditButton>
        </section>
      </section>
    </>
  )
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

如果不能如期使用则需要在父组件增加 NextIntlClientProvider 传递message参数 完成该结果

// 部分代码省略
import { NextIntlClientProvider, useMessages } from "next-intl";

// 渲染部分

const RootLayout = ({
  children,
  params,
}: Readonly<{
  children: React.ReactNode;
  params: { lang: Locale };
}>) => {
  const messages = useMessages();
  return (
    <html lang={params.lang}>
      <body className={inter.className}>
        <Provider>
          <NextIntlClientProvider messages={{ head: messages.head }}>
            <LayoutHead ></LayoutHead>
            {children}
            <LayoutFoot></LayoutFoot>
          </NextIntlClientProvider>
        </Provider>
      </body>
    </html>
  );
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

接口反向代理

为了配置反向代理,我以为需要配置 proxy 才可以,next 则不需要,只需要更改重写规则即可。

/** @type {import('next').NextConfig} */
const nextConfig = {
    async rewrites() {
        return {
            fallback: [
                {
                    source: '/capi/:path*',
                    destination: `http://127.0.0.1:3000/:path*`,
                },
            ],
        }
    },
};
export default nextConfig;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
import axios from 'axios'

let baseURL: string = "";
baseURL = "/capi"
// 拦截器
axios.interceptors.response.use((response) => {
    return response
}, (error) => {
    return Promise.reject(error)
})
axios.interceptors.request.use((config) => {
    console.log(config)
    config.headers['Accept'] = 'application/vnd.dpexpo.v1+json'
    config.baseURL = baseURL;
    config.timeout = 10000
    return config;
}, (error) => {
    return Promise.reject(error)
})

// axios的get请求
export function getAxios({
    url,
    params = {}
}: { url: string, params: any }) {
    return new Promise((resolve, reject) => {
        axios.get(url, {
            params,
        }).then(res => {
            resolve(res.data)
        }).catch(err => {
            console.log(err, '1')
            reject(err)
        })
    })
}

// axios的post请求
export function postAxios({
    url,
    data
}: any) {
    return new Promise((resolve, reject) => {
        axios({
            url,
            method: 'post',
            data
        }).then(res => {
            resolve(res.data)
        }).catch(err => {
            reject(err)
        })
    })
}

export default axios

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
import { getAxios, postAxios } from '@/utils/axios'

export const getArticle = (params: any) => {
    return getAxios({
        url: "/getArticleList",
        params
    })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

请求 /getArticleList 则对应请求的是 /capi/getArticleList

重写规则,则重定向到 [http://127.0.0.1:3000](http://127.0.0.1:3000)/getArticleList

问题来了

现在都可以实现,但是两者结合,则会报错,请求404

那怎么办?

很简单

import createMiddleware from 'next-intl/middleware';
import { locales, defaultLocale } from '@/i18n-config';

export default createMiddleware({
    locales,
    defaultLocale,
    // 默认语言不重定向
    localePrefix: 'as-needed'
});

export const config = {
   //注意观察这一样的不同 多了capi 忽略了capi的路由
    matcher: ['/((?!api|_next|_vercel|capi|.*\\..*).*)']
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/913637
推荐阅读
相关标签
  

闽ICP备14008679号