Skip to content

Fix a stale tutorial link in the feature flags tutorials list - #20045

Merged
ivanagas merged 3 commits into
masterfrom
posthog-self-driving/fixwebsite-redirect-stale-tutorial-page-db5b3a
Sep 10, 2026
Merged

Fix a stale tutorial link in the feature flags tutorials list#20045
ivanagas merged 3 commits into
masterfrom
posthog-self-driving/fixwebsite-redirect-stale-tutorial-page-db5b3a

Conversation

@posthog

@posthog posthog Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Changes

Why

The stale-tutorial report pointed at /page-data/**/page-data.json 404s, but those are Gatsby prefetch noise, not the user-facing problem: the browser redirects already send readers to the correct page. The real defect is an in-repo link that points at a tutorial path which no longer exists.

Fix

contents/docs/feature-flags/tutorials.mdx linked to /tutorials/evaluation-runtimes-and-tags. That page is now /tutorials/evaluation-runtimes-and-contexts. The link and its text now match the tutorial's current title, so the reader goes straight to the page instead of through a redirect.

vercel.json is unchanged. The page-data redirects that this PR first proposed are removed.

On /tutorials/node-external-cache

That path appears nowhere in contents/ or src/. Its only occurrence in the repository is the existing redirect source in vercel.json, which already sends readers to /docs/feature-flags/local-evaluation/distributed-environments. There is no in-repo link to fix.

Checklist

  • I've read the docs and/or content style guides.
  • Words are spelled using American English
  • Use relative URLs for internal links
  • I've checked the pages added or changed in the Vercel preview build
  • If I moved a page, I added a redirect in vercel.json

Created with PostHog Desktop from this inbox report.

Vercel matches redirect sources literally, so the browser redirects for
/tutorials/node-external-cache and
/tutorials/evaluation-runtimes-and-environments do not cover the Gatsby
page-data.json paths. Those two page-data URLs return 404.

Add a page-data redirect next to each browser redirect.

Generated-By: PostHog Desktop
Task-Id: cb742882-d196-4ebc-ac88-22b5f42511bf
@posthog

posthog Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

🦔 PostHog Review reviewed this pull request

Found 1 must fix, 0 should fix, 1 consider.

Published 2 findings (view the review).

Resolved comments: 1 fixed, 1 left for you

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Deploy preview

Status Details Updated (UTC)
🟢 Ready View preview Sep 10, 2026 09:16AM

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Bundle report

Total JS (gzip)

8.86 MiB (+0.0 KiB / +0.0%)

Eager graph (modules shipped in each entrypoint's initial chunks)

Entrypoint Eager size Budget Modules
app 18.47 MiB (+0.7 KiB / +0.0%) report-only 2054
Largest modules in the app closure
Module Size
./src/data/mcp-tools.json 1119.8 KiB
css ./node_modules/.pnpm/css-loader@5.2.7_webpack@5.101.3/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[8].oneOf[1].use[1]!./node_modules/.pnpm/postcss-loader@4.3.0_postcss@8.5.6_webpack@5.101.3/node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[8].oneOf[1].use[2]!./src/styles/global.css 761.0 KiB
./src/components/Stickers/Stickers.tsx 696.4 KiB
./node_modules/.pnpm/@radix-ui+react-icons@1.3.2_react@18.3.1/node_modules/@radix-ui/react-icons/dist/react-icons.esm.js 481.4 KiB
./node_modules/.pnpm/@posthog+brand@0.8.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/x-ray.mjs 480.8 KiB
./node_modules/.pnpm/rehype-raw@7.0.0/node_modules/rehype-raw/lib/index.js + 29 modules 395.1 KiB
./node_modules/.pnpm/@posthog+brand@0.8.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/im-the-driver.mjs 385.7 KiB
./src/hooks/useCustomers.tsx + 55 modules 370.0 KiB
./node_modules/.pnpm/@posthog+icons@0.36.6_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js 354.8 KiB
./node_modules/.pnpm/react-markdown@8.0.7_@types+react@16.14.66_react@18.3.1/node_modules/react-markdown/lib/react-markdown.js + 88 modules 351.4 KiB
./src/components/ProductComparisonTable/index.tsx + 126 modules 302.5 KiB
./node_modules/.pnpm/cloudinary-core@2.14.0_lodash@4.17.21/node_modules/cloudinary-core/cloudinary-core.js 281.9 KiB
./node_modules/.pnpm/@posthog+brand@0.8.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/doll-house.mjs 281.7 KiB
./node_modules/.pnpm/@posthog+brand@0.8.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/director.mjs 275.6 KiB
./src/components/SearchUI/index.tsx + 87 modules 273.7 KiB

Eager-graph budgets are report-only until a baseline is established. Sizes are gzip of public/**/*.js; eager size is webpack module source bytes for the modules actually shipped in the entrypoint's initial chunks (post-tree-shake).

@posthog

posthog Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

PostHog Review alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostHog Review

Found 1 must fix, 1 consider.

Comment thread vercel.json Outdated
Comment on lines +2736 to +2739
{
"source": "/page-data/tutorials/evaluation-runtimes-and-environments/page-data.json",
"destination": "/page-data/tutorials/evaluation-runtimes-and-contexts/page-data.json"
},

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Page-data redirects bypass Gatsby's client redirect flow

must_fix bug

Why we think it's a valid issue
  • Checked: Gatsby 4.25.9 (package.json:112) client runtime — cache-dir/loader.js, cache-dir/navigation.js, cache-dir/root.js — plus @gatsbyjs/reach-router 1.3.9 route matching, and searched the whole repo for createRedirect / redirectInBrowser.
  • Found: loader.js:167-186 accepts any page-data body that parses and has a path field. It makes no comparison between jsonPayload.path and the requested pagePath, so the destination document is stored under the old path.
  • Found: toPageResources (loader.js:63-77) copies path: pageData.path, and root.js:44-56 gives the single <Router> route that path while location stays on the old path. pick finds no route and reach-router returns null (es/index.js:285). The page body is empty. This confirms the empty-page mechanism.
  • Found: the present 404 is not only prefetch noise. It starts an escape hatch: loader.js:199-201 refetches /404.html with notFound: true, then ProdLoader.loadPageDataJson (loader.js:871-891) sends a HEAD request to the page URL. That request follows the existing 308 and returns 200, so the loader reports PageResourceStatus.Error, and navigation.js:93-98 does window.location = pathname. The full page load then follows the browser redirect and lands the user on the destination, ?tab=Node.js included. The new page-data rules remove the 404, so notFound is never set and this path never runs.
  • Found: no createRedirect or redirectInBrowser call exists anywhere in the repo, so maybeGetBrowserRedirect (navigation.js:12-22) holds no entry for either old path. Nothing else corrects the URL client side.
  • Impact: for in-app navigation to /tutorials/node-external-cache and /tutorials/evaluation-runtimes-and-environments, the change turns a correct (if noisy) redirect into a blank page at the old URL, and the Node reader never reaches the ?tab=Node.js destination. Direct requests and crawlers are unaffected, because the browser redirects are unchanged. Removing the two page-data rules restores today's behavior; createRedirect with redirectInBrowser: true is the mechanism that makes client navigation follow the redirect without a full load.
Issue description

Gatsby follows each new 308 redirect and receives the destination page-data document. That document contains the destination path. However, Gatsby still navigates to the old URL because Vercel redirects do not populate Gatsby's client redirect map. Reach Router then finds no matching route and can render an empty page. The Node redirect also loses its ?tab=Node.js destination.

Suggested fix

Register these URL pairs with Gatsby's actions.createRedirect and set redirectInBrowser: true. Keep the Vercel URL redirects for direct requests, but remove the page-data redirects. Test each old link through client-side navigation in a preview.

Prompt to fix with AI (copy-paste)
## Context
@vercel.json#L2736-2739
@vercel.json#L5105-5108

<issue_description>
Gatsby follows each new 308 redirect and receives the destination page-data document. That document contains the destination path. However, Gatsby still navigates to the old URL because Vercel redirects do not populate Gatsby's client redirect map. Reach Router then finds no matching route and can render an empty page. The Node redirect also loses its `?tab=Node.js` destination.
</issue_description>

<issue_validation>
- **Checked:** Gatsby 4.25.9 (`package.json:112`) client runtime — `cache-dir/loader.js`, `cache-dir/navigation.js`, `cache-dir/root.js` — plus `@gatsbyjs/reach-router` 1.3.9 route matching, and searched the whole repo for `createRedirect` / `redirectInBrowser`.
- **Found:** `loader.js:167-186` accepts any page-data body that parses and has a `path` field. It makes no comparison between `jsonPayload.path` and the requested `pagePath`, so the destination document is stored under the old path.
- **Found:** `toPageResources` (`loader.js:63-77`) copies `path: pageData.path`, and `root.js:44-56` gives the single `<Router>` route that path while `location` stays on the old path. `pick` finds no route and reach-router returns `null` (`es/index.js:285`). The page body is empty. This confirms the empty-page mechanism.
- **Found:** the present 404 is not only prefetch noise. It starts an escape hatch: `loader.js:199-201` refetches `/404.html` with `notFound: true`, then `ProdLoader.loadPageDataJson` (`loader.js:871-891`) sends a HEAD request to the page URL. That request follows the existing 308 and returns 200, so the loader reports `PageResourceStatus.Error`, and `navigation.js:93-98` does `window.location = pathname`. The full page load then follows the browser redirect and lands the user on the destination, `?tab=Node.js` included. The new page-data rules remove the 404, so `notFound` is never set and this path never runs.
- **Found:** no `createRedirect` or `redirectInBrowser` call exists anywhere in the repo, so `maybeGetBrowserRedirect` (`navigation.js:12-22`) holds no entry for either old path. Nothing else corrects the URL client side.
- **Impact:** for in-app navigation to `/tutorials/node-external-cache` and `/tutorials/evaluation-runtimes-and-environments`, the change turns a correct (if noisy) redirect into a blank page at the old URL, and the Node reader never reaches the `?tab=Node.js` destination. Direct requests and crawlers are unaffected, because the browser redirects are unchanged. Removing the two page-data rules restores today's behavior; `createRedirect` with `redirectInBrowser: true` is the mechanism that makes client navigation follow the redirect without a full load.
</issue_validation>

## Task
Investigate the issue and solve it

<potential_solution>
Register these URL pairs with Gatsby's `actions.createRedirect` and set `redirectInBrowser: true`. Keep the Vercel URL redirects for direct requests, but remove the page-data redirects. Test each old link through client-side navigation in a preview.
</potential_solution>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, and I verified the mechanism against the real Gatsby 4.25.9 client runtime rather than reasoning about it. Every step holds:

  • The page-data fetch accepts any 200 response that parses and carries a path field. It never compares that path to the path that was requested, so the destination's document gets cached under the old URL.
  • The router is then given one route, whose path comes from the loaded document (the destination), while the browser location stays on the old URL. Nothing matches, and the page renders empty. The client 404 page does not appear either, because the load counted as a success.
  • Today's 404 is load-bearing, exactly as you say. It sets notFound, which makes the loader send a HEAD request to the page URL. The existing browser redirect answers 200, the loader reports an error, and the router falls back to a full page load. That full load follows the browser redirect and lands the reader on the destination, ?tab=Node.js included.

So this PR does trade a noisy but correct redirect for a blank page on in-app navigation. I am not landing a fix unattended, and I am leaving this for a human, because both ways forward are decisions rather than mechanical changes:

  1. Register the pairs with Gatsby's createRedirect and redirectInBrowser, and drop the page-data rules. This repo has no such registration anywhere. All of the roughly 1500 redirects are hand-maintained in vercel.json, and the Gatsby build contains no redirect code at all. This would add a second, build-time source of redirects, which the repo's own contributor guide puts behind an explicit ask-first rule for build-pipeline changes. It also emits a document at the old path, which then sits alongside the existing browser redirect for that same path. Both effects are visible only on a deployed preview, and this checkout has no installed dependencies and no test that covers redirect behavior, so I cannot prove it here.
  2. Drop the two page-data rules and close the PR. This restores today's confirmed-correct behavior, but it reverts the whole change and leaves the reported page-data 404s in place.

What a human needs to decide: whether the prefetch noise is worth introducing a build-time client redirect mechanism to this site, or whether the full page load is an acceptable cost and this PR should simply be closed. Either way, please do not merge it as it stands — it is still a draft, and the two rules as committed cause the empty page you describe.

Comment thread vercel.json Outdated
The docs index linked to /tutorials/evaluation-runtimes-and-tags, a redirect
source, so in-app navigation from that link took a full page load through the
redirect. Point it at the live page and match the page's own title, which the
tags-to-contexts rename changed.

Generated-By: PostHog Desktop
Task-Id: e90c3adf-0286-421f-9929-d393f61398d6
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Vale prose linter → found 3 errors, 36 warnings, 0 suggestions in your markdown

Full report → Copy the linter results into an LLM to batch-fix issues.

Linter being weird? Update the rules!

contents/docs/feature-flags/tutorials.mdx — 3 errors, 36 warnings, 0 suggestions
Line Severity Message Rule
9:27 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
10:25 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
11:36 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
16:45 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
18:31 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
19:25 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
23:132 error Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. PostHogBase.EnDash
24:75 error Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. PostHogBase.EnDash
25:19 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
25:91 error Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. PostHogBase.EnDash
27:15 warning Capitalize 'Experiments' for PostHog's product. Use 'experiments' for the general industry concept. PostHogBase.ProductNames
27:32 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
38:26 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
40:26 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
41:24 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
42:25 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
43:25 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
44:26 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
46:26 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
47:22 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
49:39 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
50:41 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
51:36 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
52:23 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
53:22 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
54:38 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
56:24 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
57:32 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
58:25 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
59:22 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
60:21 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
61:25 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
62:47 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
63:21 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
67:18 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
71:30 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
75:4 warning Capitalize 'Feature Flags' for PostHog's product. Use 'Feature flags' for the general industry concept. PostHogBase.ProductNames
79:20 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames
80:16 warning Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. PostHogBase.ProductNames

The page-data JSON redirects are not the cause of the 404s, so drop them and keep only the stale in-repo tutorial link fix.

Generated-By: PostHog Desktop
Task-Id: cab6b9cc-92fb-4c63-988b-5fb87a846413
@github-actions github-actions Bot added the content PR only touches files under contents/ label Sep 10, 2026
@ivanagas ivanagas changed the title Add page-data redirects for two moved tutorials Fix a stale tutorial link in the feature flags tutorials list Sep 10, 2026
@ivanagas
ivanagas marked this pull request as ready for review September 10, 2026 09:03
@ivanagas
ivanagas enabled auto-merge (squash) September 10, 2026 09:03
@ivanagas
ivanagas merged commit 52015ac into master Sep 10, 2026
23 checks passed
@ivanagas
ivanagas deleted the posthog-self-driving/fixwebsite-redirect-stale-tutorial-page-db5b3a branch September 10, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

content PR only touches files under contents/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant