منبع حقیقت، محتوا، انتشار و رسانه · فصل ۲ — Page/Version/Block، Forms، SEO و Rollback · 157
Static Locale Routing with Astro
Design and verify a deterministic Astro locale-routing contract that binds supported locales, default-locale URL policy, generated paths, fallback behavior and publication eligibility to exact content/release inputs, while treating browser preference and framework helpers as signals rather than authority. میتواند «Static Locale Routing با Astro» را در یک pipeline محدود با provenance، rights/version و publication gate تعریف کند.
Lesson summary
Design and verify a deterministic Astro locale-routing contract that binds supported locales, default-locale URL policy, generated paths, fallback behavior and publication eligibility to exact content/release inputs, while treating browser preference and framework helpers as signals rather than authority.
میتواند «Static Locale Routing با Astro» را در یک pipeline محدود با provenance، rights/version و publication gate تعریف کند.
This lesson produces
میتواند «Static Locale Routing با Astro» را در یک pipeline محدود با provenance، rights/version و publication gate تعریف کند.
Who it is for
Foundation
Use a guided lesson-specific evidence matrix and one worked negative case.
Repair
Re-run only the failed owned dimension with a smaller deterministic synthetic fixture.
Experienced
Start from mixed authority/policy/evidence records; require explicit trade-offs and provenance.
Prerequisites
1. Do not confuse a generated URL with authorized localized content
Assume a static site supports fa, en, and de, with fa as the default locale. Astro may recognize /de/about/ or provide fallback behavior for it, but routing behavior does not prove that a German content record exists, is bound to the active release, and is eligible for publication. Keep three facts separate: route existence, navigation/fallback behavior, and publication eligibility. Collapsing them into one success flag can produce a healthy URL that serves the wrong or unsupported content state.
2. CON-006 ownership boundary
CON-006 owns only the static locale-routing contract: supported locales, default locale, route-policy version, prefix policy, deterministic path generation, collision handling, missing-locale state, and fallback navigation. CON-007 owns page/version workspace history; CON-008 owns forms; CON-009 owns canonical and redirect hygiene; CON-010 owns monitoring and rollback. This lesson therefore does not choose the SEO canonical or declare a release healthy. It only states what the routing layer can prove from its own bounded evidence.
3. Treat supported locales and default locale as versioned configuration
Astro i18n configuration declares locales and a defaultLocale, which must be one of the configured locales. For an auditable system, record those values in a route-policy version such as RPOL-12. Every route-matrix row references that policy so a reviewer can reconstruct which locale contract produced the path.
4. prefixDefaultLocale changes the URL set
With prefixDefaultLocale=false, a default fa page can be /about/, while a non-default locale may be /en/about/. After changing the policy to true, the same Persian content maps to /fa/about/. The content identity may be unchanged while the public route set changes. A stale path must not remain valid merely because the content ID stayed the same.
5. File-based routing and getStaticPaths are route-generation mechanisms
Astro creates routes from src/pages/, and static dynamic routes can be materialized at build time with getStaticPaths(). These mechanisms answer which URLs are generated. They do not establish MAKNOW publication authority for localized content. Intersect framework routing with exact content binding and release-manifest evidence.
6. Materialize a Locale Route Matrix
Create one row per (content_id, content_version, locale). Preserve at least: route_policy_version, default_locale, prefix_default_locale, routing_mode, generated_path, route_exists, fallback_locale, fallback_type, content_binding_status, release_manifest_ref, release_eligible, locale_collision, decision, and reason. A reviewer should be able to reconstruct the decision without hidden configuration.
7. Generate paths deterministically
For this bounded fixture, use one explicit rule: when the locale is the default and default-prefixing is disabled, the path is /{slug}/; otherwise it is /{locale}/{slug}/. This is a lesson-specific model, not a universal Astro claim. The important requirement is that the path be derived from versioned inputs. A manually supplied path that contradicts the policy is BLOCK_ROUTE_POLICY.
8. Browser preference is a signal, not content authority
Accept-Language or language-detection helpers can improve navigation, but they do not bind content. A browser preference for en must not silently replace the identity or release evidence for a fa row. Preference may influence a navigation choice; it does not create missing localized evidence.
9. Separate fallback from publication
Fallback can send a visitor to another locale when the requested locale is unavailable. If German content is missing and a valid English fallback exists, the route decision can be FALLBACK_NAVIGATION_ONLY, while German publication_eligible remains false. Fallback provides access behavior, not a German translation, approval, or release binding.
10. Preserve typed missing-locale states
When localized evidence is absent, retain states such as LOCALE_CONTENT_MISSING, CONTENT_BINDING_UNKNOWN, or FALLBACK_TARGET_UNKNOWN. If there is no valid fallback, fail closed. Typed uncertainty tells downstream teams exactly what must be produced, bound, or requalified.
11. Treat route collision as an independent failure
Two distinct records must not resolve to one public path without an explicit policy. A collision can emerge from duplicated slugs, locale aliases, or a changed prefix policy. Even when both content records are valid, routing should block rather than delegate the destination to build ordering or incidental file precedence.
12. Verify release binding independently of route_exists
route_exists=true means the build or routing layer materialized a path. PUBLISH_ROUTE_READY additionally requires verified content binding, an exact release manifest reference, and release_eligible=true. A stale, unknown, or ineligible release binding yields BLOCK_RELEASE_BINDING even if HTML exists at the URL.
13. Negative example: the German URL resolves, but German content is absent
Suppose /de/about/ resolves because of fallback or a broad route pattern, but the German content record has been removed. The tempting error is to treat route success as localized publication. The correct matrix records the navigation behavior but rejects German publication. A valid English fallback does not manufacture evidence for German content.
14. Transfer: change prefix policy and remove one translation
Switch prefixDefaultLocale from false to true. fa/about now moves from /about/ to /fa/about/. At the same time, remove the German content record while keeping the same source content ID. Rebuild the matrix from current evidence: one change affects the path set, the other affects localized-content eligibility. Do not copy the old decision.
15. Auditable output
The final artifact is Locale Route Contract & Static Route Matrix v1. For every row, a reviewer must be able to answer: Is the locale supported? What is the default locale? Which route policy produced the path? How was the path generated? Is content binding verified? Which release is bound? What does fallback do? Is there a collision? What evidence supports publication eligibility? If any decisive fact is unknown, keep it unknown; a framework helper or redirect must not convert it into success.
Assessment
There is no answer key in this lesson pack; answer it yourself and mark honestly. "Needs review" sends the lesson to your review queue.
Q1 concept
Q2 diagnosis
Q3 diagnosis
Q4 transfer
Assessment rubric
- Route contract: supported locales, default locale, policy version and prefix behavior are explicit.
- Deterministic path: generated paths match versioned route policy.
- Evidence boundary: route existence, fallback navigation and publication eligibility stay separate.
- Negative states: missing/unknown/collision/release-blocked states remain typed.
- Transfer: changed prefix policy and missing translation are rebuilt from new evidence.
References & freshness
Case studies
Lab files
Inspect the eight synthetic locale-routing fixtures and implement evaluate(case) in starter.py. Keep route generation, browser preference/fallback navigation, and localized publication eligibility separate. Recompute paths from the declared policy and preserve missing/blocked states. Final expected labels are intentionally not provided.