Pulling my Hashnode posts onto this site without a CORS proxy
I wanted this site’s Posts section to show my latest writing from recursionblog.hashnode.dev automatically, instead of manually copying links over every time I publish something.
The obvious approach doesn’t work
The straightforward idea is a client-side fetch() against the blog’s RSS
feed on page load. That fails: Hashnode’s RSS response doesn’t send an
Access-Control-Allow-Origin header, so browsers refuse to let a script on
my domain read the response, even though the exact same URL loads fine if
you open it directly in a tab. Visiting a URL yourself is a top-level
navigation; a script reading a cross-origin response is a different,
much more restricted case, and CORS is enforced by the target server, not
something I can override from my side. Hashnode’s GraphQL API, which
would’ve sidestepped this, has also moved behind a paid tier.
Fetching at build time first
The first fix was to fetch and parse the feed inside Astro’s build step, which runs in Node rather than a browser — no CORS applies to a server-to-server request. That works, but it only refreshes on the next deploy, so a new blog post wouldn’t show up here until I next pushed a commit.
A same-origin bridge
Since the site already deploys to Cloudflare Pages, the real fix was a
small Pages Function at functions/api/hashnode-posts.ts that fetches the
RSS feed server-side and re-serves it as JSON from my own domain. The
homepage’s client-side script now calls that same-origin endpoint instead
of Hashnode directly, so there’s no cross-origin request for the browser to
block in the first place. The build-time fetch still seeds the initial
render, so the section shows real content immediately and degrades
gracefully if the fetch ever fails.