Skip to content

Send old ?locale=ru|zh page addresses to the page in that language - #409

Merged
openipc-ai merged 2 commits into
masterfrom
locale-param-redirect
Oct 8, 2026
Merged

openipc-ai merged 2 commits into
masterfrom
locale-param-redirect

Conversation

@openipc-ai

Copy link
Copy Markdown
Collaborator

Follow-up to #408, from a Google and Bing audit through their APIs.

Why

Google still ranks the Rails site's ?locale= addresses: 110 of the 671 openipc.org URLs with impressions (28 days to 2026-10-05) carry a query string, and /cameras/vendors/sigmastar/socs/ssc30kq?locale=ru alone had 35 clicks. The bundle ignores the parameter, so a Russian reader got the English page, and URL inspection shows Google consolidating those addresses onto the English page ("Alternate page with proper canonical tag"). Only / handled it, in the home page's script.

Change

  • conf.d/openipc-locale-param.conf: $openipc_locale_param_target, set for GET or HEAD with ?locale=ru|zh, on an address with no /ru or /zh prefix and no dot, where the route map's action is page or catchall. Target: /ru… or /zh…, keeping the rest of the query. Built from $request_uri and $args, not the decoded $uri (no CRLF in Location).
  • The seam's location / in org.openipc and org.openipc.dev: if (...) { return 301 ...; } before try_files.
  • Addresses the route map redirects (/about?locale=zh → /community?locale=zh) are answered by the map first; the next hop localises.
  • A relative Location, so the openipc.ru mirror rewrites it to openipc.ru as it already does for the route map's 301s.

Tests

deploy/nginx/check-config.sh --seam (20 new cases, including what must not redirect: /ru/…, locale=en|de|RU, files, POST), and service/run.sh test ./deploytest/..., both pass.

Not in this PR (same audit)

  • Google: 13 sample URLs inspected, all indexed with the expected canonical; no sitemap on record in Search Console. The service account is read-only, so robots.txt's Sitemap: line (Give each chip and vendor page its own title and description; name the sitemap in robots.txt #408) is how Google finds it until the owner submits it in the UI.
  • Bing: no sitemap had ever been given; submitted via SubmitFeed (status Pending). InIndex about 8.8k is the old wall and ?locale= URLs, held back by robots.txt and fading out.

The search engines still hold the Rails site's ?locale= addresses: on
2026-10-08 Google had 110 of openipc.org's 671 URLs with impressions
carrying a query string, and
/cameras/vendors/sigmastar/socs/ssc30kq?locale=ru alone earned 35 clicks
in four weeks. The bundle ignores the parameter, so those readers got the
English page, and its canonical told the engine to keep the English one.
Only the home page's script honoured it.

The seam's `location /` in both vhosts now answers a GET or HEAD with
?locale=ru or ?locale=zh, on an address without a language of its own and
not a file, with a 301 to /ru/... or /zh/..., keeping the rest of the
query. It applies only where the route map says page or catchall; an
address the map redirects or retires is answered by the map first, and
the next hop localises. Built from $request_uri and $args, never the
decoded $uri. Relative, so openipc.ru's mirror rewrites it as it does
every other redirect.

check-config.sh --seam covers the redirects, the query handling, and the
cases that must not redirect.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Redirect legacy locale query URLs to Russian and Chinese pages

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Redirect legacy ?locale=ru|zh page requests before serving English content and its canonical
 URL.
• Preserve unrelated query parameters while leaving files, localized paths, writes, and route-map
 redirects alone.
• Cover redirect behavior and exclusions in the nginx seam checks.
Diagram

graph TD
  request["Legacy page URL"] --> seam["Site location"] --> routes["Route action"] --> maps["Locale maps"] --> eligible{"Eligible request?"} -->|Yes| redirect["Localized 301"]
  eligible -->|No| existing["Existing handling"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Extend the home page's client-side locale redirect
  • ➕ Keeps locale navigation in frontend code.
  • ➖ Cannot cover pages absent from the static bundle.
  • ➖ Serves English content and its canonical URL before redirecting.

Recommendation: Keep the nginx-seam approach. It handles indexed legacy URLs before content is served and uses the existing route map to avoid overriding redirects and retired addresses.

Files changed (4) +93 / -0

Bug fix (3) +68 / -0
openipc-locale-param.confMap eligible locale queries to localized page paths +60/-0

Map eligible locale queries to localized page paths

• Introduces nginx maps that exclude files and already-localized paths, remove the locale parameter while retaining other query arguments, and limit redirects to GET or HEAD requests classified as pages or catchalls. Builds the destination from the raw request URI rather than a decoded path.

deploy/nginx/conf.d/openipc-locale-param.conf

org.openipcRedirect eligible locale requests before production static lookup +4/-0

Redirect eligible locale requests before production static lookup

• Returns a permanent redirect from the production site’s root location when the locale maps produce a target, before 'try_files' can serve English content.

deploy/nginx/sites-available/org.openipc

org.openipc.devMirror locale redirect behavior on the development site +4/-0

Mirror locale redirect behavior on the development site

• Adds the same pre-lookup redirect to the development site’s root location, keeping its behavior aligned with production.

deploy/nginx/sites-available/org.openipc.dev

Tests (1) +25 / -0
check-config.shExercise legacy locale redirects at the nginx seam +25/-0

Exercise legacy locale redirects at the nginx seam

• Adds cases for localized redirects, query preservation, and indexed paths missing from the stub bundle. Also checks that existing localized paths, other locale values, files, and POST requests are not redirected.

deploy/nginx/check-config.sh

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Encoded locale paths lose the requested page ✓ Resolved
Description
openipc_lp_path copies the raw $request_uri path even though the route map classifies the
normalized $uri. For /%72u/donate?locale=zh, the new redirect points to /zh/%72u/donate, which
normalizes to the nonexistent /zh/ru/donate and then falls back to the Chinese home page instead
of the requested Donate page.
Code

deploy/nginx/conf.d/openipc-locale-param.conf[33]

+    "~^(?<openipc_lp_p>/[^?]*)"         $openipc_lp_p;
Evidence
The new map preserves the encoded prefix, whereas the route action uses normalized $uri; the
generated pages and localized catch-all establish the wrong final destination.

deploy/nginx/conf.d/openipc-locale-param.conf[28-34]
deploy/nginx/conf.d/openipc-locale-param.conf[50-59]
deploy/nginx/conf.d/openipc-redirects.conf[5-15]
deploy/nginx/conf.d/openipc-redirects.conf[49-50]
deploy/nginx/conf.d/openipc-redirects.conf[823-824]
frontend/apps/site/src/pages/[...path].astro[30-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The raw path can appear unprefixed while nginx routes its normalized form as an already-localized page, producing a redirect to the wrong destination.
## Fix Focus Areas
- deploy/nginx/conf.d/openipc-locale-param.conf[28-34]
- deploy/nginx/conf.d/openipc-locale-param.conf[56-60]
## Recommended Fix
Before constructing a redirect from the raw path, exclude requests whose normalized `$uri` already has a locale prefix. Add a seam test using an encoded prefix such as `/%72u/donate?locale=zh`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Repeated locale values survive redirects ✓ Resolved
Description
openipc_lp_args removes only one locale occurrence although $arg_locale can select a language
from a query containing several. For /donate?locale=ru&locale=zh, the redirect retains locale=zh
on /ru/donate, and the already-prefixed path prevents the new rule from removing that conflicting
value on the next request.
Code

deploy/nginx/conf.d/openipc-locale-param.conf[R41-42]

+    "~^locale=[^&]*&(?<openipc_lp_rest>.+)$"        "?$openipc_lp_rest";
+    "~^(?<openipc_lp_pre>.*?)&locale=[^&]*(?<openipc_lp_post>&.*)?$"  "?$openipc_lp_pre$openipc_lp_post";
Evidence
The query map strips a single occurrence and retains the remainder, while the path map excludes the
resulting localized URL from another redirect. The existing home-page handler removes all
occurrences.

deploy/nginx/conf.d/openipc-locale-param.conf[30-33]
deploy/nginx/conf.d/openipc-locale-param.conf[37-43]
deploy/nginx/conf.d/openipc-locale-param.conf[56-59]
frontend/apps/site/src/pages/index.astro[77-83]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A query with repeated `locale` parameters leaves a conflicting locale value on the redirected URL.
## Fix Focus Areas
- deploy/nginx/conf.d/openipc-locale-param.conf[37-43]
- deploy/nginx/check-config.sh[565-576]
## Recommended Fix
Make the redirect consume all `locale` occurrences, or decline to redirect ambiguous repeated values. Add seam cases with repeated matching and conflicting locale parameters.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can keep summaries lean with Findings visible per group, which tucks the rest behind a View link

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread deploy/nginx/conf.d/openipc-locale-param.conf
Comment thread deploy/nginx/conf.d/openipc-locale-param.conf
@openipc-ai
openipc-ai merged commit 93be34c into master Oct 8, 2026
2 checks passed
@openipc-ai
openipc-ai deleted the locale-param-redirect branch October 8, 2026 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant