Vibe Coding

Vibe Coding the Perfect Website for 2026

TL;DR

  • Hub-and-Spoke (Silo) model for SEO and topical authority: each interest area (Photography, Vibe Coding, Fitness, Personal, VR, Manly Beach) is a distinct hub with breadcrumb navigation and internal linking
  • Serverless tech stack: Astro (static-first, minimal JS), Cloudflare Workers + Hono (REST backend), D1 (SQLite), R2 (object storage), KV (caching), and Clerk (authentication)
  • Content architecture: Blog posts as Markdown in Git (version-controlled, searchable); user-generated content in D1; files in R2; leveraging Content Collections for topical organization
  • SEO-first design: Hierarchical URLs without dates (`/category/post-slug/`), semantic breadcrumbs, JSON-LD schema, E-E-A-T signals via author bios, and editorial post layouts with TL;DR boxes
  • Current status: Authentication flow, comment system, category hubs, post rendering, and Cloudflare Pages deployment fully operational locally and production-ready
  • Future roadmap: Fitness tracking with heatmaps, GEDCOM family tree visualization, WebXR experiments, lightweight community forums, real-time activity feeds, and R2-backed media library

I used Claude and Google Gemini Pro 3 to Vibe Code this website design, I asked Google Gemini to :

  • describe the best layout for a website with many unrelated topics, as there’s no one focus for this site just various projects that I’m working on.
  • The best layout for category/hub pages
  • The best layout for the blog post page itself
  • Font and Colour Schemes
  • URL Permalink layout

These are the instructions that were generated with I fed into Claude to build out this website layout.

I think it worked quite well so I will share all the following prompts for others to do the same.

Best Website Layout for Multi-topic Blog

This HTML and CSS template is designed specifically for a “Polymath” or Multi-topic blog. It implements the Hub-and-Spoke model by organizing content into distinct topical sections (Hubs) rather than a single list, and it includes the technical SEO elements (breadcrumbs, semantic tags) that search engines prefer in 2025.

Key SEO & Architecture Features Included:

  1. Magazine/Portal Layout: The homepage shows “Latest” from each major topic, preventing your site from looking like a random list.
  2. Hub-and-Spoke Menu: Navigation is grouped by broad categories (Hubs).
  3. Breadcrumbs: Includes semantic breadcrumb structure for Google crawlability.
  4. Right Sidebar (Desktop Only): Keeps content central for reading but provides high-value links on the side.
  5. Sticky Header: Improves user “Time on Page” by making navigation always accessible.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Polymath Blog | Multi-Topic Authority Site</title>
    <meta name="description" content="A structured hub for photography, coding, and gardening tutorials.">
    <style>
        :root {
            --primary-color: #2d3436;
            --accent-color: #0984e3;
            --bg-color: #f9f9f9;
            --text-color: #2d3436;
            --sidebar-width: 300px;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            margin: 0;
            background-color: var(--bg-color);
            color: var(--text-color);
        }

        /* --- Navigation & Hubs --- */
        header {
            background: #fff;
            border-bottom: 1px solid #ddd;
            position: sticky;
            top: 0;
            z-index: 1000;
        }

        nav {
            max-width: 1200px;
            margin: 0 auto;
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 1rem;
        }

        .logo { font-weight: bold; font-size: 1.5rem; text-decoration: none; color: var(--primary-color); }

        .nav-links { display: flex; list-style: none; gap: 20px; }
        .nav-links a { text-decoration: none; color: var(--text-color); font-weight: 500; }
        .nav-links a:hover { color: var(--accent-color); }

        /* --- Breadcrumbs (SEO Critical) --- */
        .breadcrumbs {
            max-width: 1200px;
            margin: 1rem auto;
            padding: 0 1rem;
            font-size: 0.9rem;
            color: #636e72;
        }
        .breadcrumbs a { color: var(--accent-color); text-decoration: none; }

        /* --- Layout Grid --- */
        .container {
            max-width: 1200px;
            margin: 0 auto;
            display: grid;
            grid-template-columns: 1fr var(--sidebar-width);
            gap: 40px;
            padding: 0 1rem;
        }

        /* --- Hub Sections (The "Magazine" Look) --- */
        section.hub-block {
            margin-bottom: 40px;
            background: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
        }

        .hub-title {
            border-left: 5px solid var(--accent-color);
            padding-left: 15px;
            margin-bottom: 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .post-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
        }

        .card {
            border-radius: 5px;
            overflow: hidden;
            transition: transform 0.2s;
        }
        .card:hover { transform: translateY(-5px); }
        .card img { width: 100%; height: 150px; object-fit: cover; background: #eee; }
        .card h3 { font-size: 1.1rem; margin: 10px 0; }
        .card-meta { font-size: 0.8rem; color: #b2bec3; }

        /* --- Sidebar --- */
        aside {
            display: flex;
            flex-direction: column;
            gap: 30px;
        }

        .widget {
            background: #fff;
            padding: 20px;
            border-radius: 8px;
            border: 1px solid #eee;
        }

        .tag-cloud {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
        }

        .tag {
            background: #dfe6e9;
            padding: 5px 10px;
            border-radius: 3px;
            font-size: 0.8rem;
            text-decoration: none;
            color: #2d3436;
        }

        /* --- Mobile Responsive --- */
        @media (max-width: 900px) {
            .container { grid-template-columns: 1fr; }
            aside { order: 2; }
            .nav-links { display: none; } /* In a real site, use a hamburger menu */
        }
    </style>
</head>
<body>

<header>
    <nav>
        <a href="#" class="logo">PolymathLog</a>
        <ul class="nav-links">
            <li><a href="#photography">Photography</a></li>
            <li><a href="#coding">Coding</a></li>
            <li><a href="#gardening">Gardening</a></li>
            <li><a href="#about">About</a></li>
        </ul>
    </nav>
</header>

<div class="breadcrumbs">
    <a href="#">Home</a> &gt; <span aria-current="page">Latest Updates</span>
</div>

<main class="container">
    <!-- Main Content: The "Spokes" organized by "Hubs" -->
    <div class="content">
        
        <!-- HUB 1: PHOTOGRAPHY -->
        <section id="photography" class="hub-block">
            <div class="hub-title">
                <h2>Photography Hub</h2>
                <a href="/photography" style="font-size: 0.9rem;">View All Photography &rarr;</a>
            </div>
            <div class="post-grid">
                <article class="card">
                    <img src="https://via.placeholder.com/300x150" alt="Camera lens">
                    <div class="card-meta">Dec 20, 2025 • 5 min read</div>
                    <h3><a href="/photography/sunset-tips" style="text-decoration:none; color:inherit;">5 Tips for Golden Hour Sunsets</a></h3>
                    <p style="font-size: 0.9rem;">The secret to capturing the perfect light is all about timing...</p>
                </article>
                <article class="card">
                    <img src="https://via.placeholder.com/300x150" alt="Mirrorless camera">
                    <div class="card-meta">Dec 15, 2025 • 8 min read</div>
                    <h3><a href="/photography/mirrorless-vs-dslr" style="text-decoration:none; color:inherit;">Mirrorless vs DSLR in 2026</a></h3>
                </article>
            </div>
        </section>

        <!-- HUB 2: CODING -->
        <section id="coding" class="hub-block">
            <div class="hub-title">
                <h2>Coding & Dev Hub</h2>
                <a href="/coding" style="font-size: 0.9rem;">View All Tutorials &rarr;</a>
            </div>
            <div class="post-grid">
                <article class="card">
                    <img src="https://via.placeholder.com/300x150" alt="Code on screen">
                    <div class="card-meta">Dec 18, 2025 • 12 min read</div>
                    <h3><a href="/coding/python-automation" style="text-decoration:none; color:inherit;">Automating Your Life with Python</a></h3>
                </article>
                <article class="card">
                    <img src="https://via.placeholder.com/300x150" alt="CSS Grid">
                    <div class="card-meta">Dec 10, 2025 • 6 min read</div>
                    <h3><a href="/coding/css-grid-mastery" style="text-decoration:none; color:inherit;">Mastering CSS Grid Layouts</a></h3>
                </article>
            </div>
        </section>

    </div>

    <!-- Right Sidebar (SEO & Discovery) -->
    <aside>
        <div class="widget">
            <h3>About the Author</h3>
            <p>I'm a photographer, coder, and gardener sharing what I learn along the way.</p>
        </div>

        <div class="widget">
            <h3>Top Categories</h3>
            <ul style="list-style: none; padding: 0;">
                <li><a href="/cat/photography" style="text-decoration:none;">Photography (42)</a></li>
                <li><a href="/cat/coding" style="text-decoration:none;">Coding (31)</a></li>
                <li><a href="/cat/gardening" style="text-decoration:none;">Gardening (18)</a></li>
            </ul>
        </div>

        <div class="widget">
            <h3>Tags (The Index)</h3>
            <div class="tag-cloud">
                <a href="#" class="tag">Nikon</a>
                <a href="#" class="tag">Python</a>
                <a href="#" class="tag">Organic</a>
                <a href="#" class="tag">SEO</a>
                <a href="#" class="tag">Tutorials</a>
                <a href="#" class="tag">Beginners</a>
            </div>
        </div>
    </aside>
</main>

<footer style="background: #2d3436; color: white; text-align: center; padding: 2rem; margin-top: 40px;">
    <p>&copy; 2025 Polymath Blog. Built for Authority.</p>
</footer>

</body>
</html>

Why this works for your multi-topic goal:

  1. Topical Grouping: Instead of a visitor seeing a photography post next to a gardening post in one big list, they see the “Photography Hub” and the “Coding Hub.” This satisfies Google’s need for “Topic Relevance.”
  2. Navigation Hierarchy: The menu at the top acts as the primary “Hub” links. This is the first thing Google’s crawler sees.
  3. Breadcrumbs: The Home > Latest Updates (and on subpages, Home > Photography > Post Title) creates a text-based trail that helps Google understand exactly where each post lives in your hierarchy.
  4. Tag Cloud vs. Category List: The sidebar separates broad Categories (Hubs) from specific Tags (Index items). This keeps your site organized as you grow.
  5. Single Column on Mobile: The CSS @media query ensures that on phones, the sidebar stacks below the content, providing a “mobile-first” experience which is a primary Google ranking factor.

Best Website Layout for Hub/Category Page

When someone clicks into your “Photography” Hub, they shouldn’t just see a boring list. To Google, a simple list of links looks like a “thin” page. To a user, it’s overwhelming.

The most optimal layout for a Hub page in 2025 is the Pillar-to-Grid Layout. This turns your category page into a “landing page” for that topic, which helps you rank for broad terms like “Photography Tips” instead of just individual article titles.

1. The Strategy: Why “Excerpts” win over “Full Text”

  • SEO (Duplicate Content): If you show the full text on the Hub page and the article page, Google sees two pages with identical content. This confuses the crawler and can “cannibalize” your rankings.
  • User Intent: Hub pages are for discovery. Users are scanning to find what interests them. Forcing them to scroll past 2,000 words of one article to find the next one leads to high “Bounce Rates.”
  • Speed: Loading 10 full articles with images on one page is slow. Loading 10 excerpts is instant.

2. The Anatomy of a Perfect Hub Page

A great hub page has three distinct sections:

  1. The Pillar Intro: 2–3 paragraphs of “evergreen” text explaining your expertise in this topic. This is where you put your high-level keywords.
  2. The Featured Spoke: Your absolute best, most important post in this category, highlighted at the top.
  3. The Grid: All other posts displayed as Cards (Title + Image + Excerpt).

3. Example HTML/CSS for a Hub Page

This code demonstrates a professional “Photography” hub with a pillar intro and a card grid.

<!-- Breadcrumbs for SEO -->
<nav class="breadcrumbs">
    <a href="/">Home</a> &nbsp;/&nbsp; <span>Photography</span>
</nav>

<!-- THE PILLAR INTRO: This is what helps you rank for the broad topic -->
<section class="hub-intro">
    <h1>Photography: Capturing the World</h1>
    <p>
        Welcome to my photography hub. I’ve spent over a decade mastering light, 
        composition, and the technical side of mirrorless systems. Below, you’ll 
        find my deep-dives on gear, sunset techniques, and post-processing workflows.
    </p>
    <div class="hub-stats">
        <span>42 Articles</span> | <span>Updated Dec 2025</span>
    </div>
</section>

<!-- THE GRID: Using "Cards" for better scannability -->
<main class="post-grid">
    
    <!-- Post Card 1 -->
    <article class="card">
        <div class="card-image" style="background-image: url('sunset.jpg')"></div>
        <div class="card-content">
            <span class="category-tag">Technique</span>
            <h2><a href="/photography/golden-hour">Mastering the Golden Hour</a></h2>
            <p class="excerpt">Learn the exact camera settings I use to capture vibrant, flare-free sunset photos without a tripod...</p>
            <div class="card-footer">5 min read • Jan 5, 2025</div>
        </div>
    </article>

    <!-- Post Card 2 -->
    <article class="card">
        <div class="card-image" style="background-image: url('lens.jpg')"></div>
        <div class="card-content">
            <span class="category-tag">Gear</span>
            <h2><a href="/photography/prime-lenses">Why Prime Lenses Change Everything</a></h2>
            <p class="excerpt">If you're stuck in a creative rut, zooming with your feet might be the cure. Here is why I switched...</p>
            <div class="card-footer">8 min read • Dec 12, 2024</div>
        </div>
    </article>

    <!-- Repeat for more posts -->

</main>

<style>
    /* Styling for the Hub Logic */
    .hub-intro {
        max-width: 800px;
        margin: 40px auto;
        text-align: center;
        padding: 0 20px;
    }
    .hub-intro h1 { font-size: 2.5rem; color: #2d3436; }
    .hub-intro p { font-size: 1.2rem; color: #636e72; line-height: 1.8; }

    /* The Grid System (2 columns on tablet, 3 on desktop) */
    .post-grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
        gap: 30px;
        max-width: 1200px;
        margin: 0 auto;
        padding: 20px;
    }

    /* Card Design */
    .card {
        background: #fff;
        border-radius: 12px;
        overflow: hidden;
        box-shadow: 0 4px 15px rgba(0,0,0,0.1);
        transition: transform 0.3s ease;
        display: flex;
        flex-direction: column;
    }
    .card:hover { transform: translateY(-8px); }
    
    .card-image { height: 200px; background-size: cover; background-position: center; background-color: #eee; }
    .card-content { padding: 20px; flex-grow: 1; }
    
    .category-tag { font-size: 0.7rem; text-transform: uppercase; font-weight: bold; color: #0984e3; letter-spacing: 1px; }
    .card h2 { margin: 10px 0; font-size: 1.4rem; line-height: 1.3; }
    .card h2 a { text-decoration: none; color: #2d3436; }
    .excerpt { color: #636e72; font-size: 0.95rem; margin-bottom: 20px; }
    
    .card-footer { font-size: 0.8rem; color: #b2bec3; border-top: 1px solid #f1f1f1; padding-top: 15px; }
</style>

4. How to handle “Lots of Posts” (Pagination)

As your interests grow, a single hub page might get too long.

  • Do not use Infinite Scroll: It is notoriously difficult for Google to crawl, and it breaks the “Back” button experience for users.
  • Use Pagination (Page 1, 2, 3…): This is the safest SEO bet. In Astro, you can use the built-in paginate() function to automatically split your photography collection into pages (e.g., photography/1, photography/2).

5. Summary Checklist for your Hub Pages:

  1. Title: Include the topic name (e.g., “Photography”).
  2. Intro Text: Write 200–300 words about the topic to give the page “weight” in Google’s eyes.
  3. Layout: Use a Grid of Cards.
  4. Content: Show Title + Featured Image + 150-character Excerpt.
  5. Internal Links: Ensure the “Hub” page links to the posts, and every post links back to this “Hub” (usually via Breadcrumbs or a “Back to Category” link).

Best Website Layout for a Blog Post

To rank highly in 2025, a blog post needs to satisfy two masters: The Skimmer (the human user) and The Crawler (Google/AI search engines).

The “perfect” post layout is no longer just a wall of text. It is a modular content experience.

Here is the blueprint for a high-authority post layout.


1. The Layout Architecture (Top to Bottom)

A. The Hero Header

  • Breadcrumbs: Home > Photography > Post Title. (Essential for Google to see the “Silo”).
  • H1 Title: Must be clear and include your primary keyword (e.g., “7 Best Sunset Photography Tips”).
  • Post Meta: Author name (links to bio), Published Date, and “Last Updated” date. Google rewards fresh content.
  • Reading Time: “6 min read.” This reduces bounce rates by setting expectations.
  • Featured Image: High quality, but WebP format for speed. It must have descriptive alt text.

B. The “First Scroll” (Crucial for UX)

  • The TL;DR / Key Takeaways Box: Modern best practice. Put a 3-bullet summary at the very top. This satisfies users who want an instant answer (improving “time on page” and “helpful content” signals).
  • Table of Contents: A list of “Jump Links” to your H2 headings. This allows Google to generate “Sitelinks” in search results.

C. The Content Body (The “Meat”)

  • Short Paragraphs: 2–3 sentences max. White space is your friend.
  • Semantic Headings: Use only one <h1>. Use <h2> for main points and <h3> for sub-points. Never skip levels (don’t go from H2 to H4).
  • Internal Links: Link to at least 2 other “Spokes” in your hub and 1 link back to the main “Hub” page.
  • External Links: Link to 1–2 high-authority sites (like Wikipedia or a manufacturer’s site). It shows Google you’ve done your research.
  • Rich Media: Every 500 words should have an image, a video embed, a pull-quote, or a chart.
  • Conclusion: Sum up the post.
  • Author Bio Box: This is critical for E-E-A-T (Experience, Expertise, Authoritativeness, Trustworthiness). Explain why you are qualified to write about this topic.
  • Related Posts: Show 3 posts from the same category to keep them in your “Silo.”

2. The HTML Code Structure (Semantic & SEO-Ready)

In Astro, your [slug].astro template would look like this:

<article class="post-container" itemscope itemtype="https://schema.org/BlogPosting">
  <!-- SEO Breadcrumbs -->
  <nav class="breadcrumb">...</nav>

  <header>
    <h1 itemprop="headline">7 Best Sunset Photography Tips</h1>
    <div class="meta-data">
      By <span itemprop="author">Your Name</span> | 
      Updated: <time datetime="2025-12-20">Dec 20, 2025</time>
    </div>
    
    <!-- TL;DR Box -->
    <div class="tldr-box">
      <strong>Quick Summary:</strong>
      <ul>
          <li>Use a tripod for long exposures.</li>
          <li>Shoot in RAW for better dynamic range.</li>
          <li>Focus on the foreground, not just the sky.</li>
      </ul>
    </div>
  </header>

  <!-- Sticky Table of Contents (Handled by JS or Astro) -->
  <aside class="toc">
    <h3>On this page</h3>
    <ul>
      <li><a href="#gear">Essential Gear</a></li>
      <li><a href="#settings">Camera Settings</a></li>
    </ul>
  </aside>

  <div class="entry-content" itemprop="articleBody">
    <h2 id="gear">1. Essential Gear for Sunsets</h2>
    <p>Your content goes here...</p>
    
    <!-- Example of an "Information Callout" -->
    <div class="pro-tip">
      <strong>Pro Tip:</strong> Wait 20 minutes after the sun disappears for the "Second Burn."
    </div>

    <h2 id="settings">2. Recommended Camera Settings</h2>
    <p>More great content...</p>
  </div>

  <!-- Author Bio (Critical for Google E-E-A-T) -->
  <footer class="author-card">
    <img src="avatar.jpg" alt="Your Name">
    <div>
      <h3>About the Author</h3>
      <p>I've been a professional photographer for 10 years...</p>
    </div>
  </footer>
</article>

3. Modern Best Practices for 2025

1. Optimization for “SGE” (Search Generative Experience)

AI (like Google Gemini or Perplexity) now summarizes your posts. To make sure it summarizes you correctly:

  • Use Clear Definitions: “Sunset photography is [definition].”
  • Use Lists: AI loves <ul> and <ol> tags.

2. Images: More than just “Alt Text”

  • Descriptive Filenames: Name your image sunset-photography-tripod-setup.jpg instead of IMG_1234.jpg.
  • Lazy Loading: Ensure images have loading="lazy" so the page loads faster (Astro does this well).

3. The “Sticky” Sidebar (Desktop Only)

On a desktop, keep your Table of Contents sticky on the right or left. As the user scrolls, they always know where they are. This significantly increases engagement.

4. Schema Markup (JSON-LD)

Since you are using Astro, use a script tag to inject JSON-LD Schema. This tells Google’s robot: “This is an Article, written by this person, on this date, with this image.” It’s like a business card for your code.

5. Interaction (The “Dynamic” part)

Since you mentioned Cloudflare Workers:

  • Reaction Buttons: Instead of a full comment section, add a “Was this helpful? 👍/👎” button.
  • Worker Logic: Use a Cloudflare Worker to track which posts are “Trending” and display them in your sidebar in real-time.

Summary Checklist for Every Post:

  • Primary keyword in H1, first 100 words, and one H2.
  • 3-bullet TL;DR at the top.
  • Table of Contents with jump links.
  • At least 2 internal links to other posts in the same hub.
  • Detailed Author Bio at the bottom.
  • Alt text on every image.
  • JSON-LD Schema in the head of the page.

Best Website Fonts and Colours to Use

In 2025 and moving into 2026, web design has shifted away from “flat” minimalism toward Editorial Sophistication. The goal is to make your blog look less like a “website” and more like a high-end digital magazine.

Here are the top tips for color and typography, followed by a live preview template.


1. Typography: The “Serif-Sans” Hybrid

The most modern sites now mix “Intellectual Serifs” with “Functional Sans-Serifs.”

  • The Headings (Serif): Use a high-contrast serif for H1 and H2 tags. This screams “Authority” and “Expertise.”
    • Recommendation: Playfair Display, Fraunces, or Source Serif 4.
  • The Body (Sans-Serif): For long-form reading, use a clean, highly legible sans-serif.
    • Recommendation: Inter, Outfit, or Plus Jakarta Sans.
  • The “Polymath” Touch (Mono): Use a monospaced font for small labels, dates, or code snippets. It gives a “technical” vibe to your coding posts.
    • Recommendation: JetBrains Mono or Fira Code.

2. Color: “The Zinc & Accent” Strategy

Pure black (#000000) on pure white (#ffffff) is considered “harsh” in 2025. It causes eye strain.

  • The “Zinc” Base: Use slightly off-white backgrounds (#fafafa) and deep charcoal text (#18181b). This feels premium and “expensive.”
  • Dynamic Accent Colors: Since you have many topics, use Color Siloing.
    • Photography Hub = Deep Teal
    • Coding Hub = Electric Indigo
    • Gardening Hub = Sage Green
  • Adaptive Dark Mode: Your CSS should automatically switch based on the user’s system settings.

3. Implementation: CSS Variables

Use CSS variables so you can change the “Hub” color instantly based on which category the user is in.


The Preview: Modern 2025 Blog Post Style

Copy this into an HTML file to see the typography and color scheme in action.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2025 Design Preview</title>
    <!-- Importing Modern Google Fonts -->
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500&family=Playfair+Display:ital,wght@0,700;1,700&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet">
    
    <style>
        :root {
            /* 2025 "Zinc" Palette */
            --bg-page: #fcfcfc;
            --bg-card: #ffffff;
            --text-main: #18181b;
            --text-muted: #52525b;
            --accent: #6366f1; /* Modern Indigo */
            --border: #e4e4e7;
            
            /* Typography Scales */
            --font-serif: 'Playfair Display', serif;
            --font-sans: 'Inter', sans-serif;
            --font-mono: 'JetBrains Mono', monospace;
        }

        /* Automatic Dark Mode */
        @media (prefers-color-scheme: dark) {
            :root {
                --bg-page: #09090b;
                --bg-card: #18181b;
                --text-main: #fafafa;
                --text-muted: #a1a1aa;
                --border: #27272a;
                --accent: #818cf8;
            }
        }

        body {
            background-color: var(--bg-page);
            color: var(--text-main);
            font-family: var(--font-sans);
            line-height: 1.7;
            margin: 0;
            padding: 40px 20px;
        }

        .container {
            max-width: 750px;
            margin: 0 auto;
        }

        /* Editorial Heading Style */
        .category-label {
            font-family: var(--font-mono);
            font-size: 0.75rem;
            text-transform: uppercase;
            letter-spacing: 0.1em;
            color: var(--accent);
            font-weight: 500;
        }

        h1 {
            font-family: var(--font-serif);
            font-size: 3.5rem;
            line-height: 1.1;
            margin: 10px 0 30px 0;
            letter-spacing: -0.02em;
        }

        /* 2025 Best Practice: The Summary/TL;DR Box */
        .summary-box {
            background: var(--bg-card);
            border: 1px solid var(--border);
            padding: 25px;
            border-radius: 16px;
            margin-bottom: 40px;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
        }

        .summary-box h2 {
            font-size: 1rem;
            margin-top: 0;
            font-family: var(--font-mono);
        }

        /* Body Typography */
        p {
            font-size: 1.15rem;
            margin-bottom: 1.5rem;
        }

        /* Modern Accent for Links */
        a {
            color: var(--text-main);
            text-decoration-thickness: 1px;
            text-underline-offset: 4px;
            transition: color 0.2s;
        }
        a:hover {
            color: var(--accent);
        }

        /* Pull-quote style */
        blockquote {
            font-family: var(--font-serif);
            font-style: italic;
            font-size: 1.5rem;
            border-left: 4px solid var(--accent);
            margin: 40px 0;
            padding-left: 20px;
            color: var(--text-muted);
        }

        .code-inline {
            font-family: var(--font-mono);
            background: var(--border);
            padding: 2px 6px;
            border-radius: 4px;
            font-size: 0.9em;
        }
    </style>
</head>
<body>

    <div class="container">
        <span class="category-label">Photography & Aesthetics</span>
        <h1>The subtle art of capturing light in 2026.</h1>
        
        <div class="summary-box">
            <h2>TL;DR</h2>
            <p style="font-size: 0.95rem; margin-bottom: 0;">
                In this post, we explore why high-contrast serifs are returning to the web, how to use CSS Variables for thematic siloing, and the importance of soft-white backgrounds for accessibility.
            </p>
        </div>

        <p>
            When you build a website for multiple interests, your design must act as the "glue" that holds your topics together. Whether you are writing about <strong>organic gardening</strong> or <strong>React development</strong>, a consistent typographic hierarchy provides comfort to the reader.
        </p>

        <blockquote>
            "Good design is obvious. Great design is transparent."
        </blockquote>

        <p>
            Notice how the spacing between paragraphs and the choice of a serif heading makes this feel like a <em>Journal</em> rather than a social media feed. This is how you build <strong>Authority SEO</strong>—by looking like a source that deserves to be cited.
        </p>
    </div>

</body>
</html>

Final Modern Design Tips:

  1. Stop using #000: It looks “cheap.” Use Zinc-950 (#09090b) for dark mode and Zinc-900 (#18181b) for light mode text.
  2. White Space = Luxury: Don’t be afraid of big gaps between sections. Cluttered sites look like “spam” to Google’s Quality Raters.
  3. Variable Font Weight: Use font-weight: 500 for your body text if it looks too thin on mobile.
  4. Border Radius: Use “Large” rounded corners (12px to 16px) for cards and boxes. Sharp corners feel “old web”; soft corners feel “modern app.”

Primary Structure: Hierarchical Silos

All URLs must follow the category-first pattern to establish topical authority.

The Pattern:

  • Homepage: laverty.io/
  • Hub (Category): laverty.io/photography/
  • Individual Post: laverty.io/photography/sunset-tips/
  • Tags: laverty.io/tags/photography/

Why This Is the Best Strategy

1. Topical Authority

Google’s algorithm looks at the URL string. When it sees /photography/ before the post name, it immediately assigns “weight” to that post within that niche. If you just did laverty.io/sunset-tips/, Google has to work harder to figure out if that’s a photography post or a poem about sunsets.

2. Contextual Breadcrumbs for SEO

The hierarchical structure tells search engines that posts are grouped by topic. This helps:

  • Improve category-level rankings
  • Establish your expertise in each domain
  • Make it easier for crawlers to understand content relationships

3. Future-Proof Architecture

If you decide in 3 years that your “Photography” section is so big it needs its own domain, having this structure makes the migration significantly easier. It also makes your Cloudflare Worker logic (like custom headers or caching) much simpler because you can apply rules to /photography/* or /coding/* specifically.

URL Constraints

1. No Dates in URLs

Absolute Best Practice: Remove dates from your URLs.

  • ❌ Bad: laverty.io/2023/12/05/photography/sunset-tips/
  • âś… Good: laverty.io/photography/sunset-tips/

Reasons to avoid dates:

  1. Evergreen Signal: A post from 2023 still provides value in 2025. If the date is in the URL, users are less likely to click it in search results because it looks “old.”
  2. SEO Refreshing: When you update an old post with new info, the URL stays the same.
  3. Higher Click-Through Rate: Shorter URLs have a higher CTR in search results.

2. Kebab-case Format

Use only lowercase letters and hyphens.

  • laverty.io/photography/ âś…
  • laverty.io/photography/Mastering-Light/ ❌
  • laverty.io/photography/mastering_light/ ❌

Google treats a hyphen (-) as a space, but an underscore (_) as a single character:

  • sunset-tips = “sunset” and “tips”
  • sunset_tips = “sunsettips”

3. Trailing Slashes

All URLs must end with a trailing slash for consistency.

  • laverty.io/photography/post-name/ âś…
  • laverty.io/photography/post-name ❌

Astro handles this automatically via the trailingSlash: 'always' config.

4. No File Extensions

Do not use .html or .php extensions.

  • laverty.io/photography/post-name/ âś…
  • laverty.io/photography/post-name.html ❌

Tag Organization

Tags should be treated as a secondary “Filter” layer, not a primary hierarchy.

Best Format

laverty.io/tags/programming/

Not Query Parameters

❌ Avoid: laverty.io/blog?tag=programming

Why:

  1. Query parameters are harder for Google to crawl consistently
  2. Tags create duplicate content issues if not handled with rel="noindex"
  3. The /tags/ path is more crawlable and user-friendly

SEO Consideration for Tag Pages

Use rel="noindex" on tag pages unless you have at least 5+ posts for that tag. You don’t want Google indexing “empty” pages.

Technical Best Practices

1. Lowercase Only

Always force lowercase to avoid “Duplicate Content” penalties.

  • laverty.io/Photography/Sunset is a different URL than laverty.io/photography/sunset

2. Hyphens vs Underscores

Hyphens are semantic separators in URLs.

  • sunset-tips = “sunset” and “tips”
  • sunset_tips = “sunsettips” (concatenated)

3. URL Length

Shorter URLs have higher click-through rates in search results. Keep post slugs concise but descriptive.

  • laverty.io/photography/golden-hour-tips/ âś…
  • laverty.io/photography/how-to-master-the-golden-hour-light-and-composition-techniques/ ❌

Implementation in Astro

Directory Structure

src/pages/
  index.astro                 --> laverty.io/
  tags/
    index.astro               --> laverty.io/tags/
    [tag].astro               --> laverty.io/tags/python/
  [category]/
    index.astro               --> laverty.io/photography/ (The Hub)
    [slug].astro              --> laverty.io/photography/post-name/ (The Spoke)

Dynamic Routes

The routing is handled automatically by Astro’s file-based routing system:

  1. Category Hubs: [category]/index.astro generates a hub page for each category
  2. Individual Posts: [category]/[slug].astro generates post pages with category context
  3. Tag Pages: tags/[tag].astro generates pages for each tag with rel="noindex" if fewer than 5 posts

Configuration

Ensure your astro.config.mjs includes:

export default defineConfig({
  trailingSlash: 'always',
  // ... other config
});

Handling Post Movements

If a post is moved from one category (Hub) to another:

  1. Update the file location in your src/content/blog/ directory
  2. Update the post’s category field in the frontmatter

The new URL will be automatically generated based on the updated category.

Examples

Good URL Examples

  • laverty.io/photography/ – Category hub
  • laverty.io/photography/golden-hour-tips/ – Post in photography category
  • laverty.io/programming/react-hooks-guide/ – Post in programming category
  • laverty.io/tags/typescript/ – Tag page for TypeScript
  • laverty.io/tags/ – Tag index page

Bad URL Examples (What to Avoid)

  • laverty.io/2023/12/05/photography/sunset-tips/ – Dates in URL
  • laverty.io/blog?category=photography – Query parameters instead of paths
  • laverty.io/Photography/Sunset-Tips/ – Mixed case
  • laverty.io/photography/sunset_tips – Underscores instead of hyphens
  • laverty.io/photography/sunset-tips.html – File extensions

Summary Checklist

When creating or updating a post URL:

  • Category name is lowercase and kebab-case
  • Post slug is lowercase and kebab-case
  • No dates in the URL
  • URL ends with a trailing slash
  • No query parameters
  • No file extensions
  • Post includes appropriate tags
  • Hub page for category exists at [category]/index.astro
  • Post links to category hub for navigation

Philosophy

This strategy aligns with the Hub-and-Spoke (Silo) Model for content organization. By using hierarchical URLs, you’re telling both users and search engines:

“These posts are organized by topic. Each topic has authority and depth.”

This approach makes your site more understandable, more crawlable, and more likely to rank for both specific posts AND broad category terms.

Comments (...)

Loading comments...