frontend/middleware.ts (view raw)
1import {getToken} from 'next-auth/jwt';
2import {NextRequest, NextResponse} from 'next/server';
3import {
4 ProfileDocument,
5 Enum_Userspermissionsuser_Lang as SupportedLocales,
6} from './generated/graphql';
7import {print} from 'graphql/language/printer';
8import {getCookie} from './lib/cookies';
9
10const PUBLIC_FILE = /\.(.*)$/;
11const FALLBACK_LANGUAGE = process.env.FALLBACK_LANGUAGE || 'en';
12
13export async function middleware(req: NextRequest) {
14 const isIgnoredPath =
15 req.nextUrl.pathname.startsWith('/_next') ||
16 req.nextUrl.pathname.includes('/api/') ||
17 req.nextUrl.pathname.startsWith('/graphql') ||
18 PUBLIC_FILE.test(req.nextUrl.pathname);
19
20 if (isIgnoredPath) return null;
21
22 const locale =
23 (await getRegisteredUserLanguage(req)) ||
24 getCookie('NEXT_LOCALE', req.headers.get('cookie')) ||
25 getBrowserPreferredSupportedLanguage(req) ||
26 FALLBACK_LANGUAGE;
27
28 if (req.nextUrl.locale !== locale) {
29 const url = new URL(
30 `/${locale}${req.nextUrl.pathname}${req.nextUrl.search || ''}`,
31 req.url
32 );
33 return NextResponse.redirect(url);
34 }
35}
36
37const getRegisteredUserLanguage = async req => {
38 const token = await getToken({
39 req,
40 secret: process.env.NEXTAUTH_SECRET,
41 });
42
43 const {STRAPI_URL = 'http://localhost:1337'} = process.env;
44 return fetch(`${STRAPI_URL}/graphql/`, {
45 method: 'POST',
46 headers: {
47 'Content-Type': 'application/json',
48 authorization: token?.jwt ? `Bearer ${token.jwt}` : '',
49 },
50 body: JSON.stringify({query: print(ProfileDocument)}),
51 })
52 .then(async response => {
53 const {data} = await response.json();
54 if (data?.me?.profile?.provider === 'local')
55 return data?.me?.profile?.lang;
56 })
57 .catch(console.error);
58};
59
60const getBrowserPreferredSupportedLanguage = (req): SupportedLocales => {
61 const browserAcceptedLanguages = req.headers
62 .get('accept-language')
63 ?.split(',');
64 let browserPreferredSupportedLanguage = null;
65 browserAcceptedLanguages?.every(locale => {
66 const lang = locale.split('-')?.[0].toLowerCase();
67
68 if (Object.keys(SupportedLocales).includes(lang)) {
69 browserPreferredSupportedLanguage = lang;
70 } else {
71 return false;
72 }
73 });
74 return browserPreferredSupportedLanguage;
75};