Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(language-menu): add "Remember language" experiment #11518

Merged
merged 34 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7dd78b8
chore(deps): add cookie-parser to /cloud-function
caugner Jul 23, 2024
7b79f24
refactor(cloud-function): extract canonicals module
caugner Jul 23, 2024
91de9b8
feat(cloud-function): always redirect to preferred locale
caugner Jul 23, 2024
f047dec
chore(cloud-function): ignore referer for preferred locale redirect
caugner Jul 23, 2024
6fe04de
Merge branch 'main' into MP-1242-redirect-to-preferred-locale
caugner Sep 12, 2024
213869f
refactor(language-menu): extract {get,set}CookieValue()
caugner Sep 12, 2024
1cc7ef7
fix(switch): use em instead of rem
caugner Sep 12, 2024
dcfcaa0
feat(language-menu): add automatic redirect setting
caugner Sep 12, 2024
c5a4c62
chore(language-menu): reduce item padding
caugner Sep 12, 2024
3c01161
chore(language-menu): add slight padding between items
caugner Sep 12, 2024
b72d27e
chore(language-menu): revisit thumbs confirmationg
caugner Sep 12, 2024
867749e
Merge branch 'main' into MP-1242-redirect-to-preferred-locale
caugner Sep 12, 2024
256fc31
fix(language-menu): avoid document.cookie access on SSR
caugner Sep 12, 2024
f95cb93
fix(language-menu): set preferredlocale on redirect
caugner Sep 12, 2024
a3be882
fix(language-menu): measure locale-redirct clicks
caugner Sep 12, 2024
3de136b
fix(switch): remove margin-left from label
caugner Sep 12, 2024
f5b9bad
fixup! fix(switch): use em instead of rem
caugner Sep 12, 2024
dd6a4f1
chore(language-menu): improve remember design
caugner Sep 12, 2024
a3986b2
fix(switch): correct lengths
caugner Sep 12, 2024
dc9293e
fix(thumbs): use em over rem
caugner Sep 12, 2024
dbf9392
fix(language-menu): correct spacing
caugner Sep 12, 2024
60feaee
chore(language-menu): make thumbs text italic
caugner Sep 12, 2024
258738d
feat(language-menu): reuse preferredlocale, make opt-in
caugner Sep 16, 2024
3f0fe62
chore(language-menu): clarify padding
caugner Sep 23, 2024
ddeaf6d
Apply suggestions from code review
caugner Sep 23, 2024
2f348f7
refactor(language-menu): extract cookie max-age to constant
caugner Sep 23, 2024
579b715
Merge branch 'main' into MP-1242-redirect-to-preferred-locale
LeoMcA Sep 23, 2024
afe16f1
Merge branch 'main' into MP-1242-redirect-to-preferred-locale
caugner Sep 24, 2024
c15f057
fix(language-menu): enable "Remember language" only on matching locale
caugner Sep 24, 2024
8f7819b
Merge branch 'main' into MP-1242-redirect-to-preferred-locale
caugner Sep 25, 2024
299dfc1
Merge branch 'main' into MP-1242-redirect-to-preferred-locale
caugner Sep 25, 2024
3bf6894
refactor(telemtry): rename language_{redirect => remember}
caugner Sep 25, 2024
1f640ff
fix(language-menu): set "Remember language" locale unconditionally
caugner Sep 25, 2024
5bcbea6
fix(language-menu): improve "Remember language" measurement
caugner Sep 25, 2024
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
34 changes: 34 additions & 0 deletions cloud-function/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions cloud-function/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@yari-internal/pong": "file:src/internal/pong",
"@yari-internal/slug-utils": "file:src/internal/slug-utils",
"accept-language-parser": "^1.5.0",
"cookie-parser": "^1.4.6",
"dotenv": "^16.0.3",
"express": "^4.19.2",
"http-proxy-middleware": "^3.0.0",
Expand All @@ -44,6 +45,7 @@
"devDependencies": {
"@swc/core": "^1.3.38",
"@types/accept-language-parser": "^1.5.3",
"@types/cookie-parser": "^1.4.7",
"@types/http-proxy": "^1.17.10",
"@types/http-server": "^0.12.1",
"cross-env": "^7.0.3",
Expand Down
4 changes: 4 additions & 0 deletions cloud-function/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import cookieParser from "cookie-parser";
import express, { Request, Response } from "express";
import { Router } from "express";

Expand All @@ -16,6 +17,7 @@ import { redirectMovedPages } from "./middlewares/redirect-moved-pages.js";
import { redirectEnforceTrailingSlash } from "./middlewares/redirect-enforce-trailing-slash.js";
import { redirectFundamental } from "./middlewares/redirect-fundamental.js";
import { redirectLocale } from "./middlewares/redirect-locale.js";
import { redirectPreferredLocale } from "./middlewares/redirect-preferred-locale.js";
import { redirectTrailingSlash } from "./middlewares/redirect-trailing-slash.js";
import { requireOrigin } from "./middlewares/require-origin.js";
import { notFound } from "./middlewares/not-found.js";
Expand All @@ -25,6 +27,7 @@ import { stripForwardedHostHeaders } from "./middlewares/stripForwardedHostHeade
import { proxyPong } from "./handlers/proxy-pong.js";

const router = Router();
router.use(cookieParser());
router.use(stripForwardedHostHeaders);
router.use(redirectLeadingSlash);
// MDN Plus plans.
Expand Down Expand Up @@ -85,6 +88,7 @@ router.get(
requireOrigin(Origin.main),
redirectFundamental,
redirectLocale,
redirectPreferredLocale,
redirectTrailingSlash,
redirectMovedPages,
resolveIndexHTML,
Expand Down
5 changes: 5 additions & 0 deletions cloud-function/src/canonicals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createRequire } from "node:module";

const require = createRequire(import.meta.url);

export const CANONICALS = require("../canonicals.json");
11 changes: 4 additions & 7 deletions cloud-function/src/middlewares/redirect-non-canonicals.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { createRequire } from "node:module";

import { NextFunction, Request, Response } from "express";

import { THIRTY_DAYS } from "../constants.js";
import { normalizePath, redirect } from "../utils.js";
import { CANONICALS } from "../canonicals.js";

const require = createRequire(import.meta.url);
const REDIRECTS = require("../../canonicals.json");
const REDIRECT_SUFFIXES = ["/index.json", "/bcd.json", ""];

export async function redirectNonCanonicals(
Expand All @@ -31,10 +28,10 @@ export async function redirectNonCanonicals(
);
const source = normalizePath(originalSource);
if (
typeof REDIRECTS[source] == "string" &&
REDIRECTS[source] !== originalSource
typeof CANONICALS[source] == "string" &&
CANONICALS[source] !== originalSource
) {
const target = joinPath(REDIRECTS[source], suffix) + parsedUrl.search;
const target = joinPath(CANONICALS[source], suffix) + parsedUrl.search;
if (pathname !== target) {
return redirect(res, target, {
status: 301,
Expand Down
47 changes: 47 additions & 0 deletions cloud-function/src/middlewares/redirect-preferred-locale.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { NextFunction, Request, Response } from "express";
import { normalizePath, redirect } from "../utils.js";
import { CANONICALS } from "../canonicals.js";

export async function redirectPreferredLocale(
req: Request,
res: Response,
next: NextFunction
) {
// Check 1: Does the user prefer a locale?

const preferredLocale = req.cookies["preferredlocale"];

if (!preferredLocale) {
next();
return;
}

// Check 2: Does the target have a different locale?

const target = new URL(req.url, `${req.protocol}://${req.headers.host}`);
const targetPathname = target.pathname;
const [targetLocale, targetSlug] = localeAndSlugOf(target);

if (targetLocale.toLowerCase() === preferredLocale.toLowerCase()) {
next();
return;
}

// Check 3: Does the target exist in the preferred locale?

const preferredPathname =
CANONICALS[normalizePath(`/${preferredLocale}/${targetSlug}`)] ?? null;
if (preferredPathname && preferredPathname !== targetPathname) {
const location = preferredPathname + target.search;
return redirect(res, location);
}

next();
}

function localeAndSlugOf(url: URL): [string, string] {
const locale = url.pathname.split("/").at(1) || "";
const slug = url.pathname.split("/").slice(2).join("/");

return [locale, slug];
}