Skip to content

fix: serve SPA shell for deep links on GitHub Pages - #203

Merged
bhavik-mangla merged 1 commit into
AOSSIE-Org:mainfrom
bhavik-mangla:fix/spa-deep-link-404
Aug 30, 2026
Merged

fix: serve SPA shell for deep links on GitHub Pages#203
bhavik-mangla merged 1 commit into
AOSSIE-Org:mainfrom
bhavik-mangla:fix/spa-deep-link-404

Conversation

@bhavik-mangla

@bhavik-mangla bhavik-mangla commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Addressed Issues:

Fixes #202

What was wrong

App.jsx uses BrowserRouter with real paths, but GitHub Pages serves static files only and has no rewrite rule mapping unknown paths back to the app shell. So a direct visit to — or a reload of — /overview, /contributors, /governance, etc. requested a file that does not exist on disk and Pages returned its own "File not found" page. The app never booted.

This also meant the Share button produced links that 404'd for the recipient, and sitemap.xml entries were uncrawlable.

The fix

One build-time plugin in vite.config.js that emits 404.html as a copy of index.html.

GitHub Pages serves 404.html for any unmatched path, so the app boots and React Router resolves the route from window.location. The URL is preserved — there is no redirect and no flash, which is why this is preferred over the older ?redirect= query-string workaround.

No runtime code changed, no dependency added, no change to the deploy workflow. Local npm run dev and npm run preview already had this behaviour via Vite's dev server; this closes the gap for the production Pages build.

Verification

Check Result
npm run build ✅ passes
npm test 40/40 passing (4 files)
dist/404.html emitted ✅ present
cmp dist/404.html dist/index.html ✅ byte-identical
GET /overview under GitHub Pages semantics ✅ serves app shell (id="root"), React Router resolves the route
Files changed vite.config.js only

Verified with a local static server replicating GitHub Pages' behaviour (serve the file if it exists, otherwise serve 404.html), then loaded http://localhost:8099/overview in a real browser — the OrgExplorer shell renders instead of the Pages 404.

Note: Pages still returns HTTP status 404 on the fallback response. That is inherent to this approach and does not affect rendering — the browser executes the returned document normally. This is the standard, GitHub-documented pattern for SPAs on Pages.

Additional Notes:

  • Unrelated observation while testing: CONTRIBUTING.md asks contributors to run npm run lint, but package.json has no lint script (available: dev, build, preview, test, coverage). Happy to fix that separately if useful.

Checklist

  • My code follows the project's code style and conventions
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contributing Guidelines

⚠️ AI Notice - Important!

AI assistance was used to diagnose and implement this change. The root cause was reproduced on the live site, the fix was verified locally against a server replicating GitHub Pages' static-serving behaviour, and the full build and test suite were run before submitting.

Summary by CodeRabbit

  • Bug Fixes
    • Improved navigation for direct links and deep pages when the app is hosted on GitHub Pages.
    • Added a fallback so unknown routes can load the application correctly.

GitHub Pages has no rewrite rule for client-side routes, so loading or
reloading a route such as /overview or /contributors returned the default
"File not found" page instead of the app.

Emit 404.html as a copy of index.html at build time. Pages serves it for
any unmatched path, the app boots, and React Router resolves the route
from window.location with the URL preserved.
Copilot AI lite review requested due to automatic review settings August 30, 2026 05:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added bug Something isn't working configuration Config file changes javascript JavaScript/TypeScript changes size/S 11-50 lines changed external-contributor External contributor labels Aug 30, 2026
@bhavik-mangla
bhavik-mangla merged commit 4ce2822 into AOSSIE-Org:main Aug 30, 2026
4 of 5 checks passed
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: aeababf8-43d5-4489-b959-5778e3e5ad65

📥 Commits

Reviewing files that changed from the base of the PR and between c43d64a and c8b541f.

📒 Files selected for processing (1)
  • vite.config.js

Walkthrough

The Vite configuration adds a build plugin that copies the generated index.html to 404.html when the file exists. Vite registers the plugin in its default plugin list for GitHub Pages SPA route fallback.

Changes

SPA deep-link fallback

Layer / File(s) Summary
Register SPA fallback plugin
vite.config.js
The spaDeepLinkFallback plugin resolves the output directory and copies index.html to 404.html during bundle closure. Vite registers the plugin in the default configuration.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested labels: Typescript Lang

Suggested reviewers: rahul-vyas-dev, ri1tik

Poem

A rabbit watched the build files flow
index.html took a hop below
A 404.html appeared in line
So deep links bloom on Pages fine
The routes now greet each cottontail time

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size/S 11-50 lines changed and removed size/S 11-50 lines changed labels Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working configuration Config file changes external-contributor External contributor javascript JavaScript/TypeScript changes size/S 11-50 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reloading or directly opening any route returns a GitHub Pages 404

2 participants