Back to posts

Hosting a static site without losing your mind

How to deploy a static site on Vercel, attach custom subdomains, and set up RSS — all without managing a server.

· 2 min read

Hosting a static site sounds scary in the same way “filing taxes” and “emotional availability” sound scary. You know it’s important, but you’d really like to avoid it for as long as possible.

The good news: in 2026, it doesn’t have to be.

Why static?

No server to patch, no database to back up, no runtime to monitor. Just HTML, CSS, and a sprinkle of JS served from a global CDN.

The stack I used

  • Astro for the framework — static by default, islands for interactivity
  • Vercel for hosting — free, global CDN, Git-based deploys
  • Custom subdomains — blog.arunnats.com, library.arunnats.com
  • RSS — built-in via @astrojs/rss

Step 1: Create the Astro project

npm create astro@latest my-blog -- --typescript
cd my-blog
npm install @astrojs/rss @astrojs/sitemap

Step 2: Add content collections

// src/content/config.ts
import { z, defineCollection } from 'astro:content';

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    tags: z.array(z.string()).default([]),
    draft: z.boolean().default(false),
  }),
});

export const collections = { blog };

Step 3: Build the RSS feed

// src/pages/feed.xml.ts
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';

export async function GET({ site }) {
  const posts = (await getCollection('blog'))
    .filter((p) => !p.data.draft)
    .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());

  return rss({
    title: "My Blog",
    description: "Things I write about",
    site,
    items: posts.map((post) => ({
      title: post.data.title,
      description: post.data.description,
      link: `/blog/${post.slug}/`,
      pubDate: post.data.pubDate,
      categories: post.data.tags,
    })),
  });
}

Step 4: Deploy to Vercel

  1. Push to GitHub
  2. Import in Vercel → New Project
  3. Framework preset: Astro (auto-detected)
  4. Build command: npm run build
  5. Output directory: dist

Step 5: Attach subdomains

In Vercel project → Settings → Domains:

  • Add blog.yourdomain.com
  • Vercel gives you a target like cname.vercel-dns.com
  • At your DNS provider, add: CNAME blog → cname.vercel-dns.com
  • Vercel handles TLS automatically

Step 6: Add RSS auto-discovery

In your base layout <head>:

<link rel="alternate" type="application/rss+xml" title="My Blog" href="/feed.xml" />

Done

That’s it. Push to main → Vercel builds → your static site is live with RSS, HTTPS, and a global CDN. No server management required.


Next up: building the library/bookshelf at library.arunnats.com with ~300 books and colour spines.

Published November 7, 2026