From 0bfa0a2e7b3940203f2f1eebdc40299c0948e867 Mon Sep 17 00:00:00 2001 From: Gigi Date: Fri, 7 Nov 2025 23:00:12 +0100 Subject: [PATCH 1/3] fix: gate /a/:naddr rewrite to crawlers to prevent refresh redirect - Add conditional rewrite rules in vercel.json to only serve OG HTML to crawlers - Add ?og=1 query parameter override for manual testing - Document ?og=1 testing path in README - Fixes regression where browser refresh on /a/:naddr redirected to root --- README.md | 12 ++++++++++++ vercel.json | 16 +++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ce07c53..573d6636 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,18 @@ If you bookmark something on nostr, Boris will show it in the bookmarks bar. If - If something looks empty, try opening another article and coming back — network data can arrive in bursts. - Not every article has highlights yet; they grow as the community reads. +## Development + +### Testing Open Graph Previews + +To manually test the Open Graph HTML preview for an article, append `?og=1` to any `/a/:naddr` URL: + +```text +https://read.withboris.com/a/?og=1 +``` + +This bypasses the normal SPA routing and serves the OG preview HTML directly, useful for verifying social media preview cards. + ## License MIT diff --git a/vercel.json b/vercel.json index fb4b78a1..30b864a1 100644 --- a/vercel.json +++ b/vercel.json @@ -11,7 +11,21 @@ "rewrites": [ { "source": "/a/:naddr", - "destination": "/api/article-og?naddr=:naddr" + "destination": "/api/article-og?naddr=:naddr", + "has": [ + { "type": "query", "key": "og", "value": "1" } + ] + }, + { + "source": "/a/:naddr", + "destination": "/api/article-og?naddr=:naddr", + "has": [ + { + "type": "header", + "key": "user-agent", + "value": ".*(bot|Bot|BOT|crawler|Crawler|CRAWLER|spider|Spider|facebookexternalhit|Slackbot|Twitterbot|LinkedInBot|WhatsApp|TelegramBot|Discordbot|Googlebot|bingbot|YandexBot|Baiduspider).*" + } + ] }, { "source": "/(.*)", From 63a820faf877fbafc5c497ce0242753f3bb059ca Mon Sep 17 00:00:00 2001 From: Gigi Date: Fri, 7 Nov 2025 23:00:35 +0100 Subject: [PATCH 2/3] docs: remove Development section from README --- README.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/README.md b/README.md index 573d6636..8ce07c53 100644 --- a/README.md +++ b/README.md @@ -79,18 +79,6 @@ If you bookmark something on nostr, Boris will show it in the bookmarks bar. If - If something looks empty, try opening another article and coming back — network data can arrive in bursts. - Not every article has highlights yet; they grow as the community reads. -## Development - -### Testing Open Graph Previews - -To manually test the Open Graph HTML preview for an article, append `?og=1` to any `/a/:naddr` URL: - -```text -https://read.withboris.com/a/?og=1 -``` - -This bypasses the normal SPA routing and serves the OG preview HTML directly, useful for verifying social media preview cards. - ## License MIT From 5a5cfb7edd6961d2141da0551543dab3ef748a25 Mon Sep 17 00:00:00 2001 From: Gigi Date: Fri, 7 Nov 2025 23:11:41 +0100 Subject: [PATCH 3/3] fix: use sentinel query param for OG redirect to preserve /a/:naddr paths - Change OG HTML redirect to use ?_spa=1 query param instead of redirecting to / - Simplify vercel.json rewrites: serve SPA when _spa=1, otherwise serve OG HTML - Remove brittle user-agent detection patterns - Add cleanup effect to strip _spa param from URL after SPA loads - Fixes refresh redirect regression while maintaining OG preview support --- api/services/ogHtml.ts | 5 +++-- src/App.tsx | 10 ++++++++++ vercel.json | 13 +++---------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/api/services/ogHtml.ts b/api/services/ogHtml.ts index f2713b84..0fdf52b2 100644 --- a/api/services/ogHtml.ts +++ b/api/services/ogHtml.ts @@ -60,7 +60,7 @@ ${articleTags} diff --git a/src/App.tsx b/src/App.tsx index 604f04f6..b79598cd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -755,6 +755,16 @@ function App() { } }, [showToast]) + // Strip _spa query parameter from URL after SPA loads + useEffect(() => { + const url = new URL(window.location.href) + if (url.searchParams.has('_spa')) { + url.searchParams.delete('_spa') + const path = url.pathname + (url.search ? url.search : '') + url.hash + window.history.replaceState(null, '', path) + } + }, []) + if (!eventStore || !accountManager || !relayPool) { return (
diff --git a/vercel.json b/vercel.json index 30b864a1..1fe4c857 100644 --- a/vercel.json +++ b/vercel.json @@ -11,21 +11,14 @@ "rewrites": [ { "source": "/a/:naddr", - "destination": "/api/article-og?naddr=:naddr", + "destination": "/index.html", "has": [ - { "type": "query", "key": "og", "value": "1" } + { "type": "query", "key": "_spa", "value": "1" } ] }, { "source": "/a/:naddr", - "destination": "/api/article-og?naddr=:naddr", - "has": [ - { - "type": "header", - "key": "user-agent", - "value": ".*(bot|Bot|BOT|crawler|Crawler|CRAWLER|spider|Spider|facebookexternalhit|Slackbot|Twitterbot|LinkedInBot|WhatsApp|TelegramBot|Discordbot|Googlebot|bingbot|YandexBot|Baiduspider).*" - } - ] + "destination": "/api/article-og?naddr=:naddr" }, { "source": "/(.*)",