Skip to content

hotfix: restore internal tutorials on /developers/tutorials/#18165

Merged
wackerow merged 2 commits into
masterfrom
hotfix/tutorials-isr-empty-data
May 11, 2026
Merged

hotfix: restore internal tutorials on /developers/tutorials/#18165
wackerow merged 2 commits into
masterfrom
hotfix/tutorials-isr-empty-data

Conversation

@pettinarip
Copy link
Copy Markdown
Member

@pettinarip pettinarip commented May 11, 2026

Summary

The internal tutorials list on https://ethereum.org/developers/tutorials/ is empty in production — the SSR HTML ships \"internalTutorials\":[]. Same on staging and dev.

Root cause

  1. getTutorialsData (src/lib/utils/md.ts) switched from dynamic import() to fsp.readFile(public/content/...) in #b8af05174d (Apr 1) to keep Turbopack from tracing 143k locale markdown files.
  2. The tutorials page (app/[locale]/developers/tutorials/page.tsx) also calls getAppPageContributorInfo, which goes through getGitHubContributors — wrapped with unstable_cache + revalidate: 1 day. That opts the page into ISR.
  3. After 24h, Netlify revalidates the page in its serverless function. public/content/ is not in netlify.toml [functions] included_files, so fsp.readFile throws ENOENT for every tutorial slug. The catch block swallows it and returns null → filter strips them → empty array → silently cached for the next 24h.

This is the exact failure mode documented in docs/solutions/integration-issues/netlify-isr-404-async-server-components.md. The pre-Apr-1 dynamic import() baked markdown into webpack chunks, masking the ISR/public/content mismatch.

Fix

Drop the revalidating getGitHubContributors wrapper and route getAppPageContributorInfo through getStaticGitHubContributors (no revalidate). Pages stay statically rendered with tutorial content baked in at build time. The upstream Trigger.dev job refreshes contributor data weekly, so daily revalidation was overhead anyway — contributors now refresh on deploy.

Cherry-picked from d841f7a3c9 (originally on draft PR #18146).

E2E run: https://github.com/ethereum/ethereum-org-website/actions/runs/25671352238

Test plan

  • Netlify deploy preview's /developers/tutorials/ shows internal tutorials (the bug is invisible in next dev and next start — only the serverless re-render path exposes it)
  • View source on the preview confirms \"internalTutorials\":[…] is non-empty in the SSR payload
  • Contributors strip still renders on /developers/tutorials/, /developers/, /apps/, etc.

`unstable_cache` with a finite `revalidate` opts every consuming page into
ISR. App-router pages that also read `public/content/` (e.g. the developers
hub, blog listing) then break on Netlify when the serverless re-render runs
without those files in the function bundle, silently caching empty data.

Drop the revalidating `getGitHubContributors` wrapper and route
`getAppPageContributorInfo` through `getStaticGitHubContributors`. The
upstream Trigger.dev job refreshes contributor data weekly, so the daily
revalidate was overhead anyway -- contributors now refresh on deploy.
@netlify
Copy link
Copy Markdown

netlify Bot commented May 11, 2026

Deploy Preview for ethereumorg ready!

Name Link
🔨 Latest commit 8570abc
🔍 Latest deploy log https://app.netlify.com/projects/ethereumorg/deploys/6a01c9da2d95d20008a15aa1
😎 Deploy Preview https://deploy-preview-18165.ethereum.it
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
7 paths audited
Performance: 69 (🟢 up 6 from production)
Accessibility: 96 (no change from production)
Best Practices: 100 (no change from production)
SEO: 98 (🔴 down 1 from production)
PWA: 59 (no change from production)
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions Bot added the tooling 🔧 Changes related to tooling of the project label May 11, 2026
Guard against the regression where ISR re-renders the page in Netlify's
serverless runtime, fs.readFile of public/content/ fails, and
internalTutorials silently collapses to []. External tutorials would keep
rendering from their static JSON, so the test asserts both sources
independently. When this suite runs against a deploy preview
(PLAYWRIGHT_TEST_BASE_URL set in .github/workflows/tests.yml), it exercises
the same serverless render path that hides the bug locally.
@pettinarip pettinarip force-pushed the hotfix/tutorials-isr-empty-data branch from 58aed09 to 8570abc Compare May 11, 2026 12:21
@wackerow wackerow merged commit 679f055 into master May 11, 2026
21 checks passed
@wackerow wackerow deleted the hotfix/tutorials-isr-empty-data branch May 11, 2026 14:52
@pettinarip pettinarip mentioned this pull request May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tooling 🔧 Changes related to tooling of the project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants