diff --git a/src/app/[locale]/(home)/(activities)/comments/page.tsx b/src/app/[locale]/(home)/(activities)/comments/page.tsx
index 0e6ef84f..74fa0709 100644
--- a/src/app/[locale]/(home)/(activities)/comments/page.tsx
+++ b/src/app/[locale]/(home)/(activities)/comments/page.tsx
@@ -1,11 +1,10 @@
-import { Metadata } from "next"
-
import { HomeFeed } from "~/components/home/HomeFeed"
import { APP_NAME } from "~/lib/env"
+import { withHrefLang } from "~/lib/with-hreflang"
-export const metadata: Metadata = {
+export const generateMetadata = withHrefLang(async () => ({
title: `Comments Activities - ${APP_NAME}`,
-}
+}))
export default async function FollowingActivities() {
return
diff --git a/src/app/[locale]/(home)/(activities)/following/page.tsx b/src/app/[locale]/(home)/(activities)/following/page.tsx
index fd2f70cd..8b20413e 100644
--- a/src/app/[locale]/(home)/(activities)/following/page.tsx
+++ b/src/app/[locale]/(home)/(activities)/following/page.tsx
@@ -1,11 +1,10 @@
-import { Metadata } from "next"
-
import { HomeFeed } from "~/components/home/HomeFeed"
import { APP_NAME } from "~/lib/env"
+import { withHrefLang } from "~/lib/with-hreflang"
-export const metadata: Metadata = {
+export const generateMetadata = withHrefLang(async () => ({
title: `Following Activities - ${APP_NAME}`,
-}
+}))
export default async function FollowingActivities() {
return
diff --git a/src/app/[locale]/(home)/(activities)/hottest/page.tsx b/src/app/[locale]/(home)/(activities)/hottest/page.tsx
index 5de6c79e..6b483c81 100644
--- a/src/app/[locale]/(home)/(activities)/hottest/page.tsx
+++ b/src/app/[locale]/(home)/(activities)/hottest/page.tsx
@@ -1,4 +1,3 @@
-import { Metadata } from "next"
import { getLocale } from "next-intl/server"
import { dehydrate, Hydrate } from "@tanstack/react-query"
@@ -7,11 +6,12 @@ import { HomeFeed } from "~/components/home/HomeFeed"
import { APP_NAME } from "~/lib/env"
import getQueryClient from "~/lib/query-client"
import { Language } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { prefetchGetFeed } from "~/queries/home.server"
-export const metadata: Metadata = {
+export const generateMetadata = withHrefLang(async () => ({
title: `Hottest Activities - ${APP_NAME}`,
-}
+}))
export default async function HottestActivities() {
const queryClient = getQueryClient()
diff --git a/src/app/[locale]/(home)/(activities)/latest/page.tsx b/src/app/[locale]/(home)/(activities)/latest/page.tsx
index d925a1eb..2520de4d 100644
--- a/src/app/[locale]/(home)/(activities)/latest/page.tsx
+++ b/src/app/[locale]/(home)/(activities)/latest/page.tsx
@@ -1,4 +1,3 @@
-import { Metadata } from "next"
import { getLocale } from "next-intl/server"
import { dehydrate, Hydrate } from "@tanstack/react-query"
@@ -7,11 +6,12 @@ import { HomeFeed } from "~/components/home/HomeFeed"
import { APP_NAME } from "~/lib/env"
import getQueryClient from "~/lib/query-client"
import { Language } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { prefetchGetFeed } from "~/queries/home.server"
-export const metadata: Metadata = {
+export const generateMetadata = withHrefLang(async () => ({
title: `Latest Activities - ${APP_NAME}`,
-}
+}))
export default async function LatestActivities() {
const queryClient = getQueryClient()
diff --git a/src/app/[locale]/(home)/(activities)/layout.tsx b/src/app/[locale]/(home)/(activities)/layout.tsx
index 06837fa0..9f102e4f 100644
--- a/src/app/[locale]/(home)/(activities)/layout.tsx
+++ b/src/app/[locale]/(home)/(activities)/layout.tsx
@@ -1,12 +1,11 @@
-import { Metadata } from "next"
-
import { HomeActivitiesTabs } from "~/components/home/HomeActivitiesTabs"
import { HomeSidebar } from "~/components/home/HomeSidebar"
import { APP_NAME } from "~/lib/env"
+import { withHrefLang } from "~/lib/with-hreflang"
-export const metadata: Metadata = {
+export const generateMetadata = withHrefLang(async () => ({
title: `Activities - ${APP_NAME}`,
-}
+}))
export default async function ActivitiesLayout({
children,
diff --git a/src/app/[locale]/(home)/(activities)/page.tsx b/src/app/[locale]/(home)/(activities)/page.tsx
index 911969f3..44394036 100644
--- a/src/app/[locale]/(home)/(activities)/page.tsx
+++ b/src/app/[locale]/(home)/(activities)/page.tsx
@@ -1,4 +1,3 @@
-import { Metadata } from "next"
import { getLocale } from "next-intl/server"
import { dehydrate, Hydrate } from "@tanstack/react-query"
@@ -8,11 +7,12 @@ import ShortPreviewList from "~/components/site/ShortPreviewList"
import { APP_NAME, APP_SLOGAN } from "~/lib/env"
import getQueryClient from "~/lib/query-client"
import { Language } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { getPreviewShort, prefetchGetFeed } from "~/queries/home.server"
-export const metadata: Metadata = {
+export const generateMetadata = withHrefLang(async () => ({
title: `${APP_NAME} - ${APP_SLOGAN}`,
-}
+}))
export default async function HomeActivities() {
const queryClient = getQueryClient()
diff --git a/src/app/[locale]/(home)/(activities)/search/page.tsx b/src/app/[locale]/(home)/(activities)/search/page.tsx
index cc50219d..1834e4ce 100644
--- a/src/app/[locale]/(home)/(activities)/search/page.tsx
+++ b/src/app/[locale]/(home)/(activities)/search/page.tsx
@@ -1,4 +1,3 @@
-import { Metadata } from "next"
import { getLocale } from "next-intl/server"
import { dehydrate, Hydrate } from "@tanstack/react-query"
@@ -8,19 +7,12 @@ import { HomeFeed } from "~/components/home/HomeFeed"
import { APP_NAME } from "~/lib/env"
import getQueryClient from "~/lib/query-client"
import { Language } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { prefetchGetFeed } from "~/queries/home.server"
-export function generateMetadata({
- searchParams,
-}: {
- searchParams: {
- [key: string]: string | string[] | undefined
- }
-}): Metadata {
- return {
- title: `Search: ${searchParams.q} - ${APP_NAME}`,
- }
-}
+export const generateMetadata = withHrefLang(async ({ searchParams }) => ({
+ title: `Search: ${searchParams?.q} - ${APP_NAME}`,
+}))
export default async function Search({
searchParams,
diff --git a/src/app/[locale]/(home)/(activities)/shorts/page.tsx b/src/app/[locale]/(home)/(activities)/shorts/page.tsx
index 651402f9..20acec20 100644
--- a/src/app/[locale]/(home)/(activities)/shorts/page.tsx
+++ b/src/app/[locale]/(home)/(activities)/shorts/page.tsx
@@ -1,4 +1,3 @@
-import { Metadata } from "next"
import { getLocale } from "next-intl/server"
import { dehydrate, Hydrate } from "@tanstack/react-query"
@@ -7,11 +6,12 @@ import { HomeFeed } from "~/components/home/HomeFeed"
import { APP_NAME } from "~/lib/env"
import getQueryClient from "~/lib/query-client"
import { Language } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { prefetchGetFeed } from "~/queries/home.server"
-export const metadata: Metadata = {
+export const generateMetadata = withHrefLang(async () => ({
title: `Shorts - ${APP_NAME}`,
-}
+}))
export default async function LatestActivities() {
const queryClient = getQueryClient()
diff --git a/src/app/[locale]/(home)/(activities)/tag/[tag]/page.tsx b/src/app/[locale]/(home)/(activities)/tag/[tag]/page.tsx
index 498d1ef0..1e068693 100644
--- a/src/app/[locale]/(home)/(activities)/tag/[tag]/page.tsx
+++ b/src/app/[locale]/(home)/(activities)/tag/[tag]/page.tsx
@@ -1,4 +1,3 @@
-import { Metadata } from "next"
import { getLocale } from "next-intl/server"
import { dehydrate, Hydrate } from "@tanstack/react-query"
@@ -8,19 +7,16 @@ import ParticipateButton from "~/components/home/ParticipateButton"
import { APP_NAME } from "~/lib/env"
import getQueryClient from "~/lib/query-client"
import { Language } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { prefetchGetFeed } from "~/queries/home.server"
-export function generateMetadata({
- params,
-}: {
+export const generateMetadata = withHrefLang<{
params: {
tag: string
}
-}): Metadata {
- return {
- title: `Tag: ${params.tag} - ${APP_NAME}`,
- }
-}
+}>(async ({ params }) => ({
+ title: `Tag: ${params.tag} - ${APP_NAME}`,
+}))
export default async function Tag({
params,
diff --git a/src/app/[locale]/(home)/(activities)/topic/[topic]/page.tsx b/src/app/[locale]/(home)/(activities)/topic/[topic]/page.tsx
index 0e91ad57..bdb11a9e 100644
--- a/src/app/[locale]/(home)/(activities)/topic/[topic]/page.tsx
+++ b/src/app/[locale]/(home)/(activities)/topic/[topic]/page.tsx
@@ -1,4 +1,3 @@
-import { Metadata } from "next"
import { getLocale, getTranslations } from "next-intl/server"
import { dehydrate, Hydrate } from "@tanstack/react-query"
@@ -8,22 +7,21 @@ import ParticipateButton from "~/components/home/ParticipateButton"
import { APP_NAME } from "~/lib/env"
import getQueryClient from "~/lib/query-client"
import { Language } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { prefetchGetFeed } from "~/queries/home.server"
import topics from "../../../../../../../data/topics.json"
-export function generateMetadata({
- params,
-}: {
+export const generateMetadata = withHrefLang<{
params: {
topic: string
}
-}): Metadata {
+}>(async ({ params }) => {
params.topic = decodeURIComponent(params.topic)
return {
title: `Topic: ${params.topic} - ${APP_NAME}`,
}
-}
+})
export default async function Topic({
params,
diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx
index c77fa1a8..26e7cb76 100644
--- a/src/app/[locale]/layout.tsx
+++ b/src/app/[locale]/layout.tsx
@@ -1,4 +1,3 @@
-import { Metadata } from "next"
import { NextIntlClientProvider } from "next-intl"
import { getMessages, unstable_setRequestLocale } from "next-intl/server"
import { headers } from "next/headers"
@@ -29,7 +28,9 @@ import "remark-github-alerts/styles/github-colors-dark-class.css"
import "remark-github-alerts/styles/github-base.css"
import "~/css/main.css"
-export const metadata: Metadata = {
+import { withHrefLang } from "~/lib/with-hreflang"
+
+export const generateMetadata = withHrefLang(async () => ({
title: `${APP_NAME} - ${APP_SLOGAN}`,
description: APP_DESCRIPTION,
applicationName: APP_NAME,
@@ -94,7 +95,7 @@ export const metadata: Metadata = {
site: "@_xLog",
creator: "@_xLog",
},
-}
+}))
export default async function RootLayout({
children,
diff --git a/src/app/[locale]/site/[site]/[slug]/page.tsx b/src/app/[locale]/site/[site]/[slug]/page.tsx
index 43470ea4..74fe1909 100644
--- a/src/app/[locale]/site/[site]/[slug]/page.tsx
+++ b/src/app/[locale]/site/[site]/[slug]/page.tsx
@@ -1,4 +1,3 @@
-import { Metadata } from "next"
import { getLocale, getTranslations } from "next-intl/server"
import { notFound } from "next/navigation"
import serialize from "serialize-javascript"
@@ -18,17 +17,16 @@ import { isInRN } from "~/lib/is-in-rn"
import { isOnlyContent } from "~/lib/is-only-content"
import getQueryClient from "~/lib/query-client"
import { Language } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { fetchGetPage, getSummary } from "~/queries/page.server"
import { fetchGetSite } from "~/queries/site.server"
-export async function generateMetadata({
- params,
-}: {
+export const generateMetadata = withHrefLang<{
params: {
site: string
slug: string
}
-}): Promise {
+}>(async ({ params }) => {
const queryClient = getQueryClient()
const locale = (await getLocale()) as Language
const site = await fetchGetSite(params.site, queryClient)
@@ -76,7 +74,7 @@ export async function generateMetadata({
creator: twitterCreator ? `@${twitterCreator}` : undefined,
},
}
-}
+})
export default async function SitePagePage({
params,
diff --git a/src/app/[locale]/site/[site]/archives/page.tsx b/src/app/[locale]/site/[site]/archives/page.tsx
index d92f2906..766ccca8 100644
--- a/src/app/[locale]/site/[site]/archives/page.tsx
+++ b/src/app/[locale]/site/[site]/archives/page.tsx
@@ -1,20 +1,17 @@
-import { Metadata } from "next"
-
import { dehydrate, Hydrate } from "@tanstack/react-query"
import { SiteArchives } from "~/components/site/SiteArchives"
import getQueryClient from "~/lib/query-client"
import { PageVisibilityEnum } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { prefetchGetPagesBySite } from "~/queries/page.server"
import { fetchGetSite } from "~/queries/site.server"
-export async function generateMetadata({
- params,
-}: {
+export const generateMetadata = withHrefLang<{
params: {
site: string
}
-}): Promise {
+}>(async ({ params }) => {
const queryClient = getQueryClient()
const site = await fetchGetSite(params.site, queryClient)
@@ -24,7 +21,7 @@ export async function generateMetadata({
return {
title,
}
-}
+})
export default async function SiteArchivesPage({
params,
diff --git a/src/app/[locale]/site/[site]/layout.tsx b/src/app/[locale]/site/[site]/layout.tsx
index 683533fd..ad34d933 100644
--- a/src/app/[locale]/site/[site]/layout.tsx
+++ b/src/app/[locale]/site/[site]/layout.tsx
@@ -1,4 +1,3 @@
-import { Metadata } from "next"
import { headers } from "next/headers"
import { notFound, redirect } from "next/navigation"
@@ -18,6 +17,7 @@ import { isOnlyContent, searchParser } from "~/lib/is-only-content"
import getQueryClient from "~/lib/query-client"
import { ExpandedNote } from "~/lib/types"
import { cn } from "~/lib/utils"
+import { withHrefLang } from "~/lib/with-hreflang"
import { fetchGetPage } from "~/queries/page.server"
import {
fetchGetSite,
@@ -26,13 +26,11 @@ import {
prefetchGetSiteToSubscriptions,
} from "~/queries/site.server"
-export async function generateMetadata({
- params,
-}: {
+export const generateMetadata = withHrefLang<{
params: {
site: string
}
-}): Promise {
+}>(async ({ params }) => {
const queryClient = getQueryClient()
const site = await fetchGetSite(params.site, queryClient)
@@ -80,7 +78,7 @@ export async function generateMetadata({
creator: twitterCreator,
},
}
-}
+})
export default async function SiteLayout({
children,
diff --git a/src/app/[locale]/site/[site]/nft/page.tsx b/src/app/[locale]/site/[site]/nft/page.tsx
index 81746adc..7eba65c9 100644
--- a/src/app/[locale]/site/[site]/nft/page.tsx
+++ b/src/app/[locale]/site/[site]/nft/page.tsx
@@ -1,18 +1,16 @@
-import { Metadata } from "next"
import { getTranslations } from "next-intl/server"
import { Image } from "~/components/ui/Image"
import { UniLink } from "~/components/ui/UniLink"
import getQueryClient from "~/lib/query-client"
+import { withHrefLang } from "~/lib/with-hreflang"
import { fetchGetSite, getNFTs } from "~/queries/site.server"
-export async function generateMetadata({
- params,
-}: {
+export const generateMetadata = withHrefLang<{
params: {
site: string
}
-}): Promise {
+}>(async ({ params }) => {
const queryClient = getQueryClient()
const site = await fetchGetSite(params.site, queryClient)
@@ -22,7 +20,7 @@ export async function generateMetadata({
return {
title,
}
-}
+})
export default async function SiteNFTPage({
params,
diff --git a/src/app/[locale]/site/[site]/portfolios/page.tsx b/src/app/[locale]/site/[site]/portfolios/page.tsx
index 5e900925..23c7e0a4 100644
--- a/src/app/[locale]/site/[site]/portfolios/page.tsx
+++ b/src/app/[locale]/site/[site]/portfolios/page.tsx
@@ -1,20 +1,17 @@
-import { Metadata } from "next"
-
import { dehydrate, Hydrate } from "@tanstack/react-query"
import SiteHome from "~/components/site/SiteHome"
import getQueryClient from "~/lib/query-client"
import { PageVisibilityEnum } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { prefetchGetPagesBySite } from "~/queries/page.server"
import { fetchGetSite } from "~/queries/site.server"
-export async function generateMetadata({
- params,
-}: {
+export const generateMetadata = withHrefLang<{
params: {
site: string
}
-}): Promise {
+}>(async ({ params }) => {
const queryClient = getQueryClient()
const site = await fetchGetSite(params.site, queryClient)
@@ -24,7 +21,7 @@ export async function generateMetadata({
return {
title,
}
-}
+})
async function SitePortfoliosPage({
params,
diff --git a/src/app/[locale]/site/[site]/search/page.tsx b/src/app/[locale]/site/[site]/search/page.tsx
index 99269945..85133502 100644
--- a/src/app/[locale]/site/[site]/search/page.tsx
+++ b/src/app/[locale]/site/[site]/search/page.tsx
@@ -1,33 +1,29 @@
-import { Metadata } from "next"
-
import { SearchInput } from "~/components/common/SearchInput"
import { SiteSearch } from "~/components/site/SiteSearch"
import getQueryClient from "~/lib/query-client"
+import { withHrefLang } from "~/lib/with-hreflang"
import { fetchGetSite } from "~/queries/site.server"
-export async function generateMetadata({
- params,
- searchParams,
-}: {
+export const generateMetadata = withHrefLang<{
params: {
site: string
}
searchParams: {
[key: string]: string | string[] | undefined
}
-}): Promise {
+}>(async ({ params, searchParams }) => {
const queryClient = getQueryClient()
- const site = await fetchGetSite(params.site, queryClient)
+ const site = await fetchGetSite(params?.site, queryClient)
- const title = `Search: ${searchParams.q} - ${
+ const title = `Search: ${searchParams?.q} - ${
site?.metadata?.content?.name || site?.handle
}`
return {
title,
}
-}
+})
export default async function SiteSearchPage() {
return (
diff --git a/src/app/[locale]/site/[site]/shorts/page.tsx b/src/app/[locale]/site/[site]/shorts/page.tsx
index 0fc0156f..6dbecdc6 100644
--- a/src/app/[locale]/site/[site]/shorts/page.tsx
+++ b/src/app/[locale]/site/[site]/shorts/page.tsx
@@ -1,20 +1,17 @@
-import { Metadata } from "next"
-
import { dehydrate, Hydrate } from "@tanstack/react-query"
import SiteHome from "~/components/site/SiteHome"
import getQueryClient from "~/lib/query-client"
import { PageVisibilityEnum } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { prefetchGetPagesBySite } from "~/queries/page.server"
import { fetchGetSite } from "~/queries/site.server"
-export async function generateMetadata({
- params,
-}: {
+export const generateMetadata = withHrefLang<{
params: {
site: string
}
-}): Promise {
+}>(async ({ params }) => {
const queryClient = getQueryClient()
const site = await fetchGetSite(params.site, queryClient)
@@ -24,7 +21,7 @@ export async function generateMetadata({
return {
title,
}
-}
+})
async function SiteShortsPage({
params,
diff --git a/src/app/[locale]/site/[site]/tag/[tag]/page.tsx b/src/app/[locale]/site/[site]/tag/[tag]/page.tsx
index 9e4d4660..33ab60c0 100644
--- a/src/app/[locale]/site/[site]/tag/[tag]/page.tsx
+++ b/src/app/[locale]/site/[site]/tag/[tag]/page.tsx
@@ -1,21 +1,18 @@
-import { Metadata } from "next"
-
import { dehydrate, Hydrate } from "@tanstack/react-query"
import { SiteArchives } from "~/components/site/SiteArchives"
import getQueryClient from "~/lib/query-client"
import { PageVisibilityEnum } from "~/lib/types"
+import { withHrefLang } from "~/lib/with-hreflang"
import { prefetchGetPagesBySite } from "~/queries/page.server"
import { fetchGetSite } from "~/queries/site.server"
-export async function generateMetadata({
- params,
-}: {
+export const generateMetadata = withHrefLang<{
params: {
site: string
tag: string
}
-}): Promise {
+}>(async ({ params }) => {
const queryClient = getQueryClient()
const site = await fetchGetSite(params.site, queryClient)
@@ -28,7 +25,7 @@ export async function generateMetadata({
return {
title,
}
-}
+})
export default async function SiteTagPage({
params,
diff --git a/src/i18n.ts b/src/i18n.ts
index 38a7984a..7266d7bf 100644
--- a/src/i18n.ts
+++ b/src/i18n.ts
@@ -1,6 +1,8 @@
import { getRequestConfig } from "next-intl/server"
-export const locales = ["en", "ja", "zh", "zh-TW"] as const
+import { Language } from "./lib/types"
+
+export const locales: Language[] = ["en", "ja", "zh", "zh-TW"]
export const languageNames: Record<(typeof locales)[number], string> = {
en: "English",
ja: "Japanese",
diff --git a/src/lib/types.ts b/src/lib/types.ts
index a504c842..93bf479d 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -1,6 +1,6 @@
import type { CharacterEntity, NoteEntity } from "crossbell"
-export type Language = "en" | "zh" | "zh-TW" | "ja"
+export type Language = Readonly<"en" | "zh" | "zh-TW" | "ja">
export type Site = {
id: string
diff --git a/src/lib/with-hreflang.ts b/src/lib/with-hreflang.ts
new file mode 100644
index 00000000..bc99ee8a
--- /dev/null
+++ b/src/lib/with-hreflang.ts
@@ -0,0 +1,70 @@
+import { Metadata, ResolvingMetadata } from "next"
+import { headers } from "next/headers"
+
+import { defaultLocale, locales } from "~/i18n"
+
+type BaseProps = {
+ params?: Record
+ searchParams?: Record
+}
+
+type GenerateMetadata = (
+ props: T,
+ parent: ResolvingMetadata,
+) => Promise
+
+export function withHrefLang(
+ _generateMetadata: GenerateMetadata,
+): GenerateMetadata {
+ return async function generateMetadata(
+ props: T,
+ parent: ResolvingMetadata,
+ ): Promise {
+ const metadata: Metadata = await _generateMetadata(props, parent)
+
+ if (metadata.alternates) {
+ const { locale } = props?.params || {}
+ const protocol = headers().get("x-forwarded-proto") || ""
+ const host = headers().get("x-forwarded-host") || ""
+ const metadataBase = new URL(`${protocol}://${host}`)
+ const path = headers().get("x-xlog-pathname") || ""
+
+ const redirectedPathName = (locale: string) => {
+ const search = headers().get("x-xlog-search") || ""
+ const searchParams = new URLSearchParams(search)
+ searchParams.set("locale", locale)
+
+ return `${path}?${searchParams.toString()}`
+ }
+
+ metadata.metadataBase = metadataBase
+ /**
+ * Generate hreflang.
+ * e.g. In the home page, the hreflang should be:
+ *
+ * ...
+ *
+ *
+ * ...
+ *
+ *
+ * */
+ metadata.alternates["canonical"] = redirectedPathName(
+ locale ?? defaultLocale,
+ )
+ metadata.alternates["languages"] = {
+ ...locales.reduce(
+ (acc, locale) => {
+ const hreflang: string = locale
+ acc[hreflang] = redirectedPathName(locale)
+ return acc
+ },
+ {} as Record,
+ ),
+ "x-default": redirectedPathName("en"),
+ }
+ }
+
+ return metadata
+ }
+}
diff --git a/src/middleware.ts b/src/middleware.ts
index d5d5a3fa..3e2f2ad0 100644
--- a/src/middleware.ts
+++ b/src/middleware.ts
@@ -6,6 +6,7 @@ import { getClientIp } from "@supercharge/request-ip"
import { IS_PROD } from "~/lib/constants"
import { defaultLocale, locales } from "./i18n"
+import { Language } from "./lib/types"
// HTTPWhiteListPaths: White list of path for plain http request, no HTTPS redirect
const HTTPWhitelistPaths = ["/api/healthcheck"]
@@ -17,7 +18,7 @@ export const config = {
}
export async function middleware(req: NextRequest) {
- const handleI18nRouting = createMiddleware({
+ const handleI18nRouting = createMiddleware({
locales,
defaultLocale,
localePrefix: "never",
@@ -25,6 +26,13 @@ export async function middleware(req: NextRequest) {
const { pathname } = req.nextUrl
+ const searchParams = new URLSearchParams(req.nextUrl.search)
+ const specifiedLocale = searchParams.get("locale") as Language | undefined
+
+ if (specifiedLocale && locales.includes(specifiedLocale)) {
+ req.cookies.set("NEXT_LOCALE", specifiedLocale)
+ }
+
if (
IS_PROD &&
req.headers.get("x-forwarded-proto") !== "https" &&