MCPcopy
hub / github.com/vercel/next.js / getAcceptLanguageLocale

Function getAcceptLanguageLocale

packages/next-routing/src/i18n.ts:95–157  ·  view source on GitHub ↗
(
  acceptLanguageHeader: string,
  locales: string[]
)

Source from the content-addressed store, hash-verified

93 * Parses the Accept-Language header and returns the best matching locale
94 */
95export function getAcceptLanguageLocale(
96 acceptLanguageHeader: string,
97 locales: string[]
98): string | undefined {
99 if (!acceptLanguageHeader || !locales.length) {
100 return undefined
101 }
102
103 try {
104 // Parse accept-language header
105 const languages = acceptLanguageHeader
106 .split(',')
107 .map((lang) => {
108 const parts = lang.trim().split(';')
109 const locale = parts[0]
110 let quality = 1
111
112 if (parts[1]) {
113 const qMatch = parts[1].match(/q=([0-9.]+)/)
114 if (qMatch && qMatch[1]) {
115 quality = parseFloat(qMatch[1])
116 }
117 }
118
119 return { locale, quality }
120 })
121 .filter((lang) => lang.quality > 0)
122 .sort((a, b) => b.quality - a.quality)
123
124 // Create lowercase lookup for locales
125 const localeLookup = new Map<string, string>()
126 for (const locale of locales) {
127 localeLookup.set(locale.toLowerCase(), locale)
128 }
129
130 // Try to find exact match first
131 for (const { locale } of languages) {
132 const normalized = locale.toLowerCase()
133 if (localeLookup.has(normalized)) {
134 return localeLookup.get(normalized)
135 }
136 }
137
138 // Try prefix matching (e.g., "en-US" matches "en")
139 for (const { locale } of languages) {
140 const prefix = locale.toLowerCase().split('-')[0]
141 if (localeLookup.has(prefix)) {
142 return localeLookup.get(prefix)
143 }
144
145 // Also check if any configured locale starts with this prefix
146 for (const [key, value] of localeLookup) {
147 if (key.startsWith(prefix + '-')) {
148 return value
149 }
150 }
151 }
152

Callers 2

i18n.test.tsFile · 0.90
detectLocaleFunction · 0.85

Calls 11

splitMethod · 0.80
trimMethod · 0.80
toLowerCaseMethod · 0.80
startsWithMethod · 0.80
matchMethod · 0.65
setMethod · 0.65
getMethod · 0.65
sortMethod · 0.45
filterMethod · 0.45
mapMethod · 0.45
hasMethod · 0.45

Tested by

no test coverage detected