← All posts

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.