Skip to content

Commit dd764d7

Browse files
authoredAug 24, 2022
feat: add setting for setting expiration of the cookie that stores locale (#1492)
1 parent f8f0759 commit dd764d7

File tree

5 files changed

+41
-19
lines changed

5 files changed

+41
-19
lines changed
 

‎docs/content/en/options-reference.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,20 @@ Directory that contains translation files to load. Can be used with or without l
131131
## `detectBrowserLanguage`
132132

133133
- type: `object`
134-
- default: `{ alwaysRedirect: false, fallbackLocale: '', redirectOn: 'root', useCookie: true, cookieCrossOrigin: false, cookieDomain: null, cookieKey: 'i18n_redirected', cookieSecure: false }`
134+
- default:
135+
```js
136+
{
137+
alwaysRedirect: false,
138+
fallbackLocale: '',
139+
redirectOn: 'root',
140+
useCookie: true,
141+
cookieAge: 365,
142+
cookieCrossOrigin: false,
143+
cookieDomain: null,
144+
cookieKey: 'i18n_redirected',
145+
cookieSecure: false,
146+
}
147+
```
135148

136149
Enables browser language detection to automatically redirect visitors to their preferred locale as they visit your site for the first time.
137150

@@ -151,6 +164,7 @@ Supported properties:
151164
- `root` (recommended for improved SEO) - only detect the browser locale on the root path (`/`) of the site. Only effective when using strategy other than `'no_prefix'`.
152165
- `no prefix` - a more permissive variant of `root` that will detect the browser locale on the root path (`/`) and also on paths that have no locale prefix (like `/foo`). Only effective when using strategy other than `'no_prefix'`.
153166
- `useCookie` (default: `true`) - If enabled, a cookie is set once the user has been redirected to browser's preferred locale, to prevent subsequent redirections. Set to `false` to redirect every time.
167+
- `cookieAge` (default: `365`) - Sets the max age of the cookie in days.
154168
- `cookieKey` (default: `'i18n_redirected'`) - Cookie name.
155169
- `cookieDomain` (default: `null`) - Set to override the default domain of the cookie. Defaults to the **host** of the site.
156170
- `cookieCrossOrigin` (default: `false`) - When `true`, sets the flags `SameSite=None; Secure` on the cookie to allow cross-domain use of the cookie (required when app is embedded in an iframe).

‎src/helpers/constants.js

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const DEFAULT_OPTIONS = {
4444
rootRedirect: null,
4545
detectBrowserLanguage: {
4646
alwaysRedirect: false,
47+
cookieAge: 365,
4748
cookieCrossOrigin: false,
4849
cookieDomain: null,
4950
cookieKey: 'i18n_redirected',

‎src/templates/plugin.main.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export default async (context) => {
4747
fallbackLocale,
4848
redirectOn,
4949
useCookie,
50+
cookieAge,
5051
cookieKey,
5152
cookieDomain,
5253
cookieSecure,
@@ -298,7 +299,7 @@ export default async (context) => {
298299
i18n.differentDomains = options.differentDomains
299300
i18n.onBeforeLanguageSwitch = options.onBeforeLanguageSwitch
300301
i18n.onLanguageSwitched = options.onLanguageSwitched
301-
i18n.setLocaleCookie = locale => setLocaleCookie(locale, res, { useCookie, cookieDomain, cookieKey, cookieSecure, cookieCrossOrigin })
302+
i18n.setLocaleCookie = locale => setLocaleCookie(locale, res, { useCookie, cookieAge, cookieDomain, cookieKey, cookieSecure, cookieCrossOrigin })
302303
i18n.getLocaleCookie = () => getLocaleCookie(req, { useCookie, cookieKey, localeCodes: options.localeCodes })
303304
i18n.setLocale = (locale) => loadAndSetLocale(locale)
304305
i18n.getBrowserLocale = () => getBrowserLocale()

‎src/templates/utils-common.js

+22-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { parse as cookieParse, serialize as cookieSerialize } from 'cookie'
22
import JsCookie from 'js-cookie'
33

4-
/** @typedef {import('../../types/internal').ResolvedOptions} ResolvedOptions */
4+
/**
5+
* @typedef {import('../../types/internal').ResolvedOptions} ResolvedOptions
6+
* @typedef {Required<import('../../types/').DetectBrowserLanguageOptions>} DetectBrowserLanguageOptions
7+
*/
58

69
/**
710
* Formats a log message, prefixing module's name to it.
@@ -185,34 +188,36 @@ export function getLocaleCookie (req, { useCookie, cookieKey, localeCodes }) {
185188
/**
186189
* @param {string} locale
187190
* @param {import('http').ServerResponse | undefined} res
188-
* @param {{ useCookie: boolean, cookieDomain: string | null, cookieKey: string, cookieSecure: boolean, cookieCrossOrigin: boolean}} options
191+
* @param {Pick<DetectBrowserLanguageOptions, 'useCookie' | 'cookieAge' | 'cookieDomain' | 'cookieKey' | 'cookieSecure' | 'cookieCrossOrigin'>} options
189192
*/
190-
export function setLocaleCookie (locale, res, { useCookie, cookieDomain, cookieKey, cookieSecure, cookieCrossOrigin }) {
193+
export function setLocaleCookie (locale, res, { useCookie, cookieAge, cookieDomain, cookieKey, cookieSecure, cookieCrossOrigin }) {
191194
if (!useCookie) {
192195
return
193196
}
194-
const date = new Date()
195-
/** @type {import('cookie').CookieSerializeOptions} */
196-
const cookieOptions = {
197-
expires: new Date(date.setDate(date.getDate() + 365)),
198-
path: '/',
199-
sameSite: cookieCrossOrigin ? 'none' : 'lax',
200-
secure: cookieCrossOrigin || cookieSecure
201-
}
202-
203-
if (cookieDomain) {
204-
cookieOptions.domain = cookieDomain
205-
}
206-
207197
if (process.client) {
208-
// @ts-ignore
198+
/** @type {import('js-cookie').CookieAttributes} */
199+
const cookieOptions = {
200+
expires: cookieAge,
201+
path: '/',
202+
sameSite: cookieCrossOrigin ? 'none' : 'lax',
203+
secure: cookieCrossOrigin || cookieSecure,
204+
...cookieDomain ? { domain: cookieDomain } : {}
205+
}
209206
JsCookie.set(cookieKey, locale, cookieOptions)
210207
} else if (res) {
211208
let headers = res.getHeader('Set-Cookie') || []
212209
if (!Array.isArray(headers)) {
213210
headers = [String(headers)]
214211
}
215212

213+
/** @type {import('cookie').CookieSerializeOptions} */
214+
const cookieOptions = {
215+
maxAge: cookieAge * 60 * 60 * 24, // in seconds
216+
path: '/',
217+
sameSite: cookieCrossOrigin ? 'none' : 'lax',
218+
secure: cookieCrossOrigin || cookieSecure,
219+
...cookieDomain ? { domain: cookieDomain } : {}
220+
}
216221
const redirectCookie = cookieSerialize(cookieKey, locale, cookieOptions)
217222
headers = headers.filter(header => {
218223
const cookie = cookieParse(header)

‎types/index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface LocaleObject extends Record<string, any> {
1818

1919
export interface DetectBrowserLanguageOptions {
2020
alwaysRedirect?: boolean
21+
cookieAge?: number
2122
cookieCrossOrigin?: boolean
2223
cookieDomain?: string | null
2324
cookieKey?: string

0 commit comments

Comments
 (0)