Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions i18n.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -377,24 +377,6 @@
"dateFormat": "MM/DD/YYYY",
"validISO639_1": true
},
{
"code": "pcm",
"crowdinCode": "pcm",
"name": "Nigerian Pidgin",
"localName": "Nigerian Pidgin",
"langDir": "ltr",
"dateFormat": "DD/MM/YYYY",
"validISO639_1": false
},
{
"code": "fil",
"crowdinCode": "fil",
"name": "Filipino",
"localName": "Filipino",
"langDir": "ltr",
"dateFormat": "MM/DD/YYYY",
"validISO639_1": false
},
{
"code": "pl",
"crowdinCode": "pl",
Expand Down
42 changes: 34 additions & 8 deletions middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,44 @@ import createMiddleware from "next-intl/middleware"

import { routing } from "./src/i18n/routing"
import { DEFAULT_LOCALE } from "./src/lib/constants"
import { getFirstSegment } from "./src/lib/utils/url"

const handleI18nRouting = createMiddleware(routing)

// Locales that have been removed but may have external links pointing to them
const DEPRECATED_LOCALES = new Set(["pcm", "fil", "ph"])

// Legacy locale codes that should redirect to their current equivalents
const LOCALE_ALIASES: Record<string, string> = { no: "nb" }

function redirectTo(request: NextRequest, pathname: string, status: number) {
const url = request.nextUrl.clone()
url.pathname = pathname
return NextResponse.redirect(url, status)
}

export default function middleware(request: NextRequest) {
// Normalize to lowercase paths site-wide (URLs are case-insensitive by spec,
// but our routes are defined in lowercase). Do this BEFORE i18n routing.
const originalPath = request.nextUrl.pathname
const lowerPath = originalPath.toLowerCase()
if (originalPath !== lowerPath) {
const url = request.nextUrl.clone()
url.pathname = lowerPath
return NextResponse.redirect(url, 301)
const { pathname } = request.nextUrl

const lowerPath = pathname.toLowerCase()
if (pathname !== lowerPath) {
return redirectTo(request, lowerPath, 301)
}

const firstSegment = getFirstSegment(lowerPath)

if (firstSegment && DEPRECATED_LOCALES.has(firstSegment)) {
// Strip deprecated locale and redirect to default locale version
const rest = lowerPath.slice(firstSegment.length + 1)
const newPath = !rest ? "/" : rest
return redirectTo(request, newPath, 302)
}

if (firstSegment && firstSegment in LOCALE_ALIASES) {
// Replace legacy locale code with current one
const newLocale = LOCALE_ALIASES[firstSegment]
const newPath = `/${newLocale}${lowerPath.slice(firstSegment.length + 1)}`
return redirectTo(request, newPath, 301)
}

// Handle i18n routing
Expand Down
4 changes: 0 additions & 4 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,6 @@ module.exports = (phase, { defaultConfig }) => {
}

return [
// Custom locale aliases redirects
{ source: "/no/:path*", destination: "/nb/:path*", permanent: true },
{ source: "/ph/:path*", destination: "/fil/:path*", permanent: true },
Comment on lines -166 to -167
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@corwintines @wackerow these redirects for deprecated locales (/pcm, /fil, /ph) and the Norwegian alias (/no → /nb) were working fine locally but not on Netlify.

The reson is that, on Netlify Edge, the next-intl middleware runs before Next.js processes the redirects in next.config.js. So when someone hit /pcm/some-page, the middleware intercepted it first, didn't recognize pcm as a valid locale, and returned a 404 instead of redirecting to the English version.

By handling these locale redirects directly in the middleware (before next-intl does its thing), we ensure they work consistently everywhere — local dev, Netlify preview deploys, and prod.


// All primary redirects
...redirects.flatMap(([source, destination, permanent]) =>
createRedirect(source, destination, permanent)
Expand Down
139 changes: 0 additions & 139 deletions public/content/translations/fil/bridges/index.md

This file was deleted.

Loading