404 Error on Root URL After Locale Redirection in Next.js Middleware i18n issue #12995
Unanswered
rohithroshan-r
asked this question in
Help
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
`import {
checkServiceability,
CryptoChainCode,
CurrencyCode,
getPostRampOrderFlow,
getPreRampOrderFlow,
OrderType,
} from "client"
import {
DEFAULT_PAGE,
ERROR_PAGE,
ORDER_CONFIRM_PAGE,
PAYMENT_PROCESSING_PAGE,
QUOTE_PAGE,
WALLET_ADDRESS_PAGE,
} from "constants/routes"
import { ACTION_REDIRECT_MAP, BANNER_PARAMS } from "lib/utils"
import { type JWT } from "next-auth/jwt"
import { withAuth } from "next-auth/middleware"
import { NextRequest, NextResponse } from "next/server"
import { match as matchLocale } from "@formatjs/intl-localematcher"
import { i18n } from "i18n-config"
import Negotiator from "negotiator"
export function getLocale(request: NextRequest): string | undefined {
const negotiatorHeaders: Record<string, string> = {}
request.headers.forEach((value, key) => (negotiatorHeaders[key] = value))
const locales = i18n.locales ?? "en"
let languages = new Negotiator({ headers: negotiatorHeaders }).languages(
locales as any,
)
const locale = matchLocale(languages, locales, i18n.defaultLocale)
return locale
}
function getAuthToken(request: NextRequest) {
let authToken = request.cookies.get("__Secure-next-auth.session-token")?.value
if (!authToken) {
authToken = request.cookies.get("next-auth.session-token")?.value
}
return authToken
}
async function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname
const pathnameIsMissingLocale = i18n.locales.every(
(locale) =>
!pathname.startsWith(
/${locale}/
) && pathname !==/${locale}
,)
if (pathnameIsMissingLocale) {
const locale = getLocale(request)
return NextResponse.redirect(
new URL(
/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}
,request.url,
),
)
}
const isLocaleRoot = i18n.locales.some((locale) => pathname ===
/${locale}
)try {
if (isLocaleRoot || pathname === DEFAULT_PAGE) {
const newUrl = new URL(QUOTE_PAGE, request.url)
return NextResponse.redirect(newUrl)
}
} catch (error) {
console.error("Request failed:", error)
return NextResponse.redirect(new URL(ERROR_PAGE, request.url))
}
return NextResponse.next()
}
async function handleCheckServiceability(request: NextRequest) {
const forwardedFor = request.headers.get("x-forwarded-for") || ""
const ipAddress = forwardedFor.split(",")[0].trim()
const response = await checkServiceability({
baseURL: process.env.API_BASE_URL,
query: { ipAddress: ipAddress },
validateStatus: () => true,
})
if (response.data?.code === 100019) {
return handleActionFlow(request, "region_blocked", {})
}
if (response.data?.code !== 0) {
throw response.data?.message ?? "Unknown error"
}
return NextResponse.next()
}
async function handlePreOrderFlow(request: NextRequest) {
const searchParams = request.nextUrl.searchParams
const query = {
orderType: (searchParams.get("orderType") as OrderType) ?? undefined,
srcAmount: searchParams.get("srcAmount") ?? undefined,
srcCurrency: (searchParams.get("srcCurrency") as CurrencyCode) ?? undefined,
srcChain: (searchParams.get("srcChain") as CryptoChainCode) ?? undefined,
dstCurrency: (searchParams.get("dstCurrency") as CurrencyCode) ?? undefined,
dstChain: (searchParams.get("dstChain") as CryptoChainCode) ?? undefined,
walletAddress: searchParams.get("walletAddress") ?? undefined,
walletAddressTag: searchParams.get("walletAddressTag") ?? undefined,
orderUid: searchParams.get("orderUid") ?? undefined,
apiKey: searchParams.get("apiKey") ?? undefined,
}
const response = await getPreRampOrderFlow({
baseURL: process.env.API_BASE_URL,
headers: { Authorization:
Bearer ${getAuthToken(request)}
},query,
})
const flow = response?.data?.data?.flow ?? ""
let params: Record<string, string> = {}
const kycSessionData = response?.data?.data?.kycSessionData
if (kycSessionData?.webData) {
params.kycData = kycSessionData.webData
params.kycLevel = String(kycSessionData.kycLevel)
}
const walletUid = response?.data?.data?.walletUid
if (walletUid) {
params.walletUid = walletUid
}
return handleActionFlow(request, flow, params)
}
async function handlePostOrderFlow(request: NextRequest) {
const response = await getPostRampOrderFlow({
baseURL: process.env.API_BASE_URL,
headers: { Authorization:
Bearer ${getAuthToken(request)}
},query: { orderUid: request.nextUrl.searchParams.get("orderUid") ?? "" },
})
const flow = response?.data?.data?.flow ?? ""
return handleActionFlow(request, flow, {})
}
async function handleActionFlow(
request: NextRequest,
flow: string,
params: Record<string, string>,
) {
if (flow == "proceed") {
return NextResponse.next()
}
const redirectPath = ACTION_REDIRECT_MAP[flow]
if (!redirectPath) {
throw new Error(
invalid_flow: ${flow}
)}
if (request.nextUrl.pathname === redirectPath) {
// Scenario:
// - User is already in a redirected path
// - Makes a call to the middleware again
// - But the action flow is still the same
return NextResponse.next()
}
const nextUrl = new URL(redirectPath, request.url)
const currentUrl = request.nextUrl.pathname + request.nextUrl.search
nextUrl.searchParams.append("redirectUrl", currentUrl)
Object.keys(params).forEach((key) => {
nextUrl.searchParams.append(key, params[key])
})
if (BANNER_PARAMS[flow]) {
nextUrl.searchParams.append("message", BANNER_PARAMS[flow])
}
return NextResponse.redirect(nextUrl)
}
function authorizedCallback(params: {
token: JWT | null
req: NextRequest
}): boolean {
const pathname = params.req.nextUrl.pathname
if (
pathname === DEFAULT_PAGE ||
pathname.startsWith(QUOTE_PAGE) ||
pathname.startsWith(WALLET_ADDRESS_PAGE) ||
pathname.startsWith("/api/ramp") ||
pathname.startsWith(ERROR_PAGE)
) {
return true
}
return !!params.token
}
export default withAuth(middleware, {
callbacks: {
authorized: authorizedCallback,
},
})
export const config = {
matcher: [
"/((?!_next/static|_next/image|favicon.ico|.\.(?:svg|png|jpg|jpeg|gif|webp)$).)",
],
}
`
Beta Was this translation helpful? Give feedback.
All reactions