FeaturesTemplatesShowcaseTownie
AI
BlogDocsPricing
Log inSign up
valdottown

valdottown

blog

Val Town's Blog
Public
Like
8
blog
Home
Code
7
components
3
posts
3
routes
4
utils
6
README.md
TODOs.md
H
index.ts
Branches
5
Pull requests
1
Remixes
16
History
Environment variables
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
posts
/
vt-blog.md
Code
/
posts
/
vt-blog.md
Search
4/2/2025
Viewing readonly version of main branch: v26
View latest version
vt-blog.md
title:
Migrating the Val Town Blog to Val Town
description:
How we migrated the Val Town Blog from Astro & Cloudflare Pages to be hosted directly on Val Town in a day
pubDate:
2025-04-02T00:00:00.000Z
author:
Steve Krouse

Today I migrated the Val Town Blog from Astro and Cloudflare Pages to be hosted directly on Val Town. With some cleverness and a bit of vibe coding, I was able to start and complete this migration in a day.

The Old Architecture

Previously, our blog was:

  • Built with Astro, a modern static site generator
  • Deployed to Cloudflare Pages
  • Updated through a GitHub workflow

While this setup worked well, we wanted:

  1. A browser-based editor
  2. Instant deploys (on feature branches and production)
  3. To dogfood

The New Architecture

The new blog:

  1. Hosts new blog posts directly on Val Town as markdown files
  2. Proxies requests for old blog posts to the original Cloudflare Pages deployment
  3. Generates the full lists of posts (for the homepage) by splicing together the new posts and the old posts, which it gets via the old blog's RSS feed

Technical Implementation

We implemented the new blog system using:

  • React for rendering components
  • Tailwind CSS for styling
  • Unified/Remark/Rehype for markdown processing
  • RSS Parser for fetching posts from the old blog

Rendering old posts

Proxying is as easy as:

Create val
const OLD_BLOG_URL = "https://val-town-blog.pages.dev/"; const response = await fetch( new Request(OLD_BLOG_URL + url.pathname + url.search, { method: request.method, headers: new Headers({ ...Object.fromEntries(request.headers) }), }), );

Fetching old posts

We fetch old posts via the https://val-town-blog.pages.dev/rss.xml, and combine them with the locally-hosted posts. We cache them both in-memory on server startup.

Create val
// Example of how we fetch blog posts async function getAllBlogPosts() { // Get local posts from markdown files const localPosts = await getLocalBlogPosts(); // Get posts from RSS feed const rssPosts = await getRssBlogPosts(); // Merge and sort by date return [...localPosts, ...rssPosts].sort((a, b) => { return new Date(b.pubDate).getTime() - new Date(a.pubDate).getTime(); }); }

Conclusion

So far we've had reasonable success with this technique of migrating to Val Town quickly by proxying most old content, and only rebuilding the homepage. I first used this technique on my personal website, stevekrouse.com, and was pleased to see it continue to work here. If you, dear reader, have a blog you'd like to migrate to Val Town in this way and get stuck, shoot me an email at steve@val.town – I'd be happy to help.

FeaturesVersion controlCode intelligenceCLI
Use cases
TeamsAI agentsSlackGTM
ExploreDocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareersBrandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.