divmagic Make design
SimpleNowLiveFunMatterSimple
Rebuilding a Hand-Coded Website with Astro: A Modern Frontend Workflow Guide
BlogsAstroRebuilding a Hand-Coded Website with Astro: A Modern Frontend Workflow Guide
Astro

Rebuilding a Hand-Coded Website with Astro: A Modern Frontend Workflow Guide

Introduction

For years, hand-coding a website was the gold standard for developers who wanted full control over every line of HTML, CSS, and JavaScript. It offered unmatched flexibility and a deep understanding of the codebase. But as websites grow, more pages, more content, more complexity, that hand-coded approach can become a maintenance nightmare. You find yourself copying and pasting navigation bars, updating footers across dozens of files, and manually optimizing assets for performance.

That's exactly the situation the author of the How-To Geek article found themselves in. Their website, last redesigned around 2018, had grown from supporting six or seven books to many more. The manual patching and adding had become unsustainable. The solution? Rebuilding the entire site with Astro, a modern static site generator that promises speed, simplicity, and a better developer experience.

In this post, we'll dissect that migration journey, explore the technical decisions behind it, and show you how you can apply the same principles to your own projects. Whether you're maintaining a personal blog, a portfolio, or a documentation site, the lessons here are directly applicable.

Enter Astro: The Static Site Generator That Respects Your Code

Astro is a relatively new static site generator that has quickly gained popularity among frontend developers. Its core philosophy is simple: ship zero JavaScript by default, and only load client-side scripts when absolutely necessary. This approach leads to incredibly fast page loads and a smaller carbon footprint.

But what makes Astro particularly appealing for rebuilding a hand-coded website is its component-based architecture. You can create reusable components for headers, footers, cards, and layouts, then compose them into pages. This eliminates the repetitive boilerplate that plagues hand-coded sites.

The Migration Process: Step by Step

Let's walk through the actual steps the author took to rebuild their site with Astro. We'll focus on the technical decisions and code examples that made the transition successful.

Step 1: Setting Up the Astro Project

First, you need to initialize a new Astro project. The official CLI makes this straightforward:

npm create astro@latest my-new-site

During setup, you'll be prompted to choose a template. For a content-heavy site, the "Blog" template is a great starting point. It includes Markdown support, RSS feed generation, and a basic layout.

Once the project is created, you can start customizing the structure. The key folders are:

  • src/pages/, Each file here becomes a route.
  • src/layouts/, Reusable layout components.
  • src/components/, Smaller UI components.
  • public/, Static assets like images and fonts.

Step 2: Extracting the Layout

In a hand-coded site, every page likely contains the same <header>, <nav>, and <footer> markup. With Astro, you create a single layout component that wraps your page content.

---
// src/layouts/BaseLayout.astro
export interface Props {
  title: string;
  description?: string;
}
const { title, description } = Astro.props;
---
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>{title}</title>
  {description && <meta name="description" content={description} />}
  <link rel="stylesheet" href="/styles/global.css" />
</head>
<body>
  <header>
    <nav>
      <a href="/">Home</a>
      <a href="/blog">Blog</a>
      <a href="/about">About</a>
    </nav>
  </header>
  <main>
    <slot /> <!-- Page content goes here -->
  </main>
  <footer>
    <p>&copy; 2025 My Site</p>
  </footer>
</body>
</html>

Now every page can use this layout with just a few lines:

---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout title="About Me" description="Learn more about the author.">
  <h1>About Me</h1>
  <p>I'm a frontend developer who loves Astro.</p>
</BaseLayout>

This single change eliminates hundreds of lines of duplicated HTML across the site.

Step 4: Reusable Components for UI Elements

Beyond layouts, Astro components let you encapsulate any UI pattern. For example, a book card component that displays a cover image, title, and description can be reused across multiple pages.

---
// src/components/BookCard.astro
export interface Props {
  title: string;
  cover: string;
  description: string;
  url: string;
}
const { title, cover, description, url } = Astro.props;
---
<article class="book-card">
  <img src={cover} alt={title} loading="lazy" />
  <h3>{title}</h3>
  <p>{description}</p>
  <a href={url}>Learn More</a>
</article>

<style>
  .book-card {
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    padding: 1rem;
    max-width: 300px;
  }
  .book-card img {
    width: 100%;
    height: auto;
    border-radius: 4px;
  }
</style>

Now you can use this component anywhere:

<BookCard
  title="Astro for Beginners"
  cover="/images/astro-book.jpg"
  description="A comprehensive guide to building fast websites with Astro."
  url="/books/astro-for-beginners"
/>

This component-based approach not only saves time but also ensures visual consistency across the site.

Performance Gains: What the Numbers Say

One of the most compelling reasons to migrate to Astro is performance. By shipping zero JavaScript by default, Astro pages load incredibly fast. Let's look at some typical improvements.

Performance Metrics: Hand-Coded vs Astro

SEO and Accessibility Improvements

Rebuilding with Astro also opens the door to better SEO and accessibility practices. Here are some specific improvements you can implement.

Semantic HTML and Structured Data

Astro encourages writing semantic HTML because you're composing components rather than copying and pasting. You can easily add structured data (JSON-LD) to your pages for better search engine understanding.

---
// src/components/SEO.astro
const { title, description, url, image } = Astro.props;
---

  "@context": "https://schema.org",
  "@type": "WebPage",
  "name": title,
  "description": description,
  "url": url,
  "image": image,
})} />

Then include this component in your layout:

<SEO title={title} description={description} url={Astro.url} image="/og-image.jpg" />

Automatic Sitemap Generation

Astro has an official sitemap integration that generates a sitemap.xml file at build time. This is crucial for SEO because it helps search engines discover all your pages.

npm install @astrojs/sitemap

Then add it to your astro.config.mjs:

import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://example.com',
  integrations: [sitemap()],
});

That's it. Every page in your src/pages/ directory will be included in the sitemap automatically.

The Developer Experience: Why Astro Wins

Beyond performance, the developer experience of working with Astro is a major reason to migrate. Here are some aspects that the How-To Geek author likely appreciated.

Hot Module Replacement (HMR)

When you're developing locally, Astro's dev server provides instant feedback. Change a component, and the browser updates without a full page reload. This is a huge productivity boost compared to manually refreshing the browser after every edit.

Integration Ecosystem

Astro has a growing ecosystem of integrations for popular tools:

  • Tailwind CSS: For utility-first styling.
  • React, Vue, Svelte: Use your favorite framework components inside Astro.
  • MDX: Embed React components directly in Markdown.
  • Image optimization: Automatic resizing and format conversion.
  • RSS feed: Generate RSS feeds from your content collections.

This means you're not locked into a single framework. You can use the best tool for each job.

TypeScript Support

Astro has first-class TypeScript support. You can define props interfaces for your components, which catches errors at build time rather than runtime.

---
interface Props {
  title: string;
  date: Date;
  excerpt: string;
  tags: string[];
}
const { title, date, excerpt, tags } = Astro.props;
---
<article>
  <h2>{title}</h2>
  <time datetime={date.toISOString()}>{date.toLocaleDateString()}</time>
  <p>{excerpt}</p>
  <ul>
    {tags.map(tag => <li>{tag}</li>)}
  </ul>
</article>

This catches type errors early and makes your code more maintainable.

Common Pitfalls and How to Avoid Them

Migrating from a hand-coded site to Astro is generally smooth, but there are a few common pitfalls to watch out for.

1. Over-Engineering the Component Tree

It's tempting to create a component for everything, even a single paragraph. But that can lead to unnecessary complexity. Start with the most repetitive elements (layout, navigation, cards) and only create components when you see a pattern repeating three or more times.

2. Ignoring the Build Process

Astro generates a static site, but you still need to configure the build process. Make sure your astro.config.mjs includes the correct site URL for the sitemap, and that your image optimization settings match your needs.

3. Not Using Content Collections for Structured Data

If you have a list of items (books, blog posts, portfolio pieces), use Content Collections. They provide type safety, automatic pagination, and easy filtering. Manually listing items in a component is a step backward.

4. Forgetting About 404 Pages

Hand-coded sites often have a custom 404 page. In Astro, you create a 404.astro file in src/pages/. It will be served automatically for any route that doesn't exist.

---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout title="Page Not Found">
  <h1>404</h1>
  <p>Sorry, the page you're looking for doesn't exist.</p>
  <a href="/">Go back home</a>
</BaseLayout>

Real-World Results: What the Author Achieved

The How-To Geek article provides a candid look at the migration process. The author didn't just rebuild the site, they also improved the content structure, added new features, and optimized for performance.

Conclusion: Is Astro Right for Your Hand-Coded Site?

If you're maintaining a hand-coded website that has grown beyond a few pages, migrating to Astro is likely a smart move. The benefits are clear:

  • Faster development: Reusable components and Markdown content reduce repetitive work.
  • Better performance: Zero JavaScript by default leads to lightning-fast pages.
  • Improved SEO: Automatic sitemaps, structured data, and optimized images boost search rankings.
  • Easier maintenance: Update a component once, and it changes everywhere.

The migration process itself is straightforward. Start by setting up a new Astro project, extract your layout into a component, then convert your pages to Markdown or Astro files. Use Content Collections for structured data, and take advantage of the integration ecosystem for images, SEO, and more.

Astro isn't just a tool, it's a philosophy. It respects the craftsmanship of hand-coded sites while providing the automation and scalability that modern web development demands. If you're ready to leave the copy-paste cycle behind, give Astro a try.

Start Building with DivMagic Today

Join 10,000+ developers, designers, and business owners to copy code from any website and use it in their own projects.

Get DivMagic for 42% off

Limited time deal for 22:45