Skip to content
Public template

About

Own your foundation. A production-ready template for the modern business.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

Astro Website Template

Astro Tailwind CSS Cloudflare License: MIT

Own your foundation. A production-ready template for agencies and professional services—fast, secure, and designed to be extended.

image

What You Get

  • Beautiful by default — Warm, elegant design with Cormorant Garamond serif + Source Sans 3
  • Self-hosted fonts — Built-in Fonts API downloads and serves fonts from your domain (no Google Fonts requests, better privacy and performance)
  • One-pager structure — Hero, Services, About, Testimonial, Process, and Contact sections
  • Blog ready — Content collections with Markdown, RSS feeds, and related posts
  • SEO optimized — Meta tags, Open Graph, Twitter cards, JSON-LD schema, sitemaps, and robots.txt
  • Security headers — CSP, X-Frame-Options, Referrer-Policy configured out of the box
  • Analytics ready — Optional PostHog integration with event tracking
  • Cloudflare native — Wrangler config for staging and production deployments
  • Mobile-first — Responsive design tested across all breakpoints

Prerequisites

  • Bun — JavaScript runtime and package manager
  • Node.js 22+ — Required by Astro 7
  • just — Command runner; required for the deploy recipes, which apply safeguards a bare wrangler deploy skips

Quick Start

# Clone the repository
git clone https://github.com/socialtide/astro-template my-site
cd my-site

# Remove template git history
rm -rf .git && git init

# Install dependencies
bun install

# Start development server
bun dev

Your site is running at http://localhost:4321

Customization

1. Update Your Brand

Edit src/data/site.json:

{
  "siteName": "Your Brand",
  "siteUrl": "https://yourdomain.com",
  "defaultTitle": "Your Brand | Growing Businesses with Clarity",
  "defaultDescription": "Your compelling description...",
  "contact": {
    "email": "hello@yourdomain.com",
    "phone": "+1 (234) 567-890"
  }
}

2. Update Navigation

Edit src/data/navigation.json:

{
  "logo": { "text": "Your Brand", "href": "/" },
  "mainNav": [
    { "label": "Services", "href": "#services" },
    { "label": "About", "href": "#about" },
    { "label": "Blog", "href": "/blog/" }
  ],
  "ctaButton": { "label": "Get in Touch", "href": "#contact" }
}

3. Customize Colors

Edit src/styles/global.css to change the color palette:

@theme {
  /* Primary - Warm terracotta (or your brand color) */
  --color-primary-500: oklch(0.58 0.14 35);

  /* Accent - Sage green */
  --color-accent-500: oklch(0.55 0.08 145);

  /* Warm neutrals - Cream to charcoal */
  --color-warm-50: oklch(0.985 0.008 85); /* Background */
  --color-warm-900: oklch(0.18 0.015 55); /* Text */
}

Tip: Use oklch.com to experiment with colors

4. Customize Fonts

Fonts are configured in astro.config.mjs using Astro's built-in Fonts API. They're downloaded at build time and served from your domain — no external requests to Google Fonts.

fonts: [
  {
    name: "Your Serif Font",
    cssVariable: "--font-cormorant-garamond",
    provider: fontProviders.google(),
  },
  // ...
],

Then update the theme variables in src/styles/global.css to reference your new font:

@theme {
  --font-family-serif: var(--font-your-serif-font);
}

5. Replace Content

  • Homepage sections — Edit src/pages/index.astro
  • Images — Replace placeholders with your photography
  • Blog posts — Add Markdown files to src/content/blog/

Project Structure

├── src/
│   ├── components/
│   │   └── common/        # Header, Footer
│   ├── content/
│   │   └── blog/          # Blog posts (Markdown)
│   ├── content.config.ts  # Content collection schemas + loaders
│   ├── data/              # Site & navigation config
│   ├── layouts/           # Page layouts with SEO
│   ├── pages/             # Routes
│   └── styles/            # Global CSS + Tailwind theme
├── public/                # Static assets
├── astro.config.mjs       # Astro + fonts configuration
└── wrangler.toml          # Cloudflare deployment config

Blog Posts

Create Markdown files in src/content/blog/:

---
title: "Your Post Title"
description: "Brief description for previews and SEO"
author: "Your Name"
date: 2025-01-15
tags: ["business", "strategy"]
featured: true
readingTime: 5
---

Your content here...

Form Handling

The contact form is wired to SocialTide Harbor by default. Set PUBLIC_SOCIALTIDE_CLIENT_ID, PUBLIC_SOCIALTIDE_API_BASE, and optionally PUBLIC_TURNSTILE_SITE_KEY to enable submissions. See docs/FORM_SETUP.md for:

  • SocialTide Harbor setup (default)
  • Google Sheets integration via Apps Script
  • Custom API endpoints
  • Cloudflare Turnstile spam protection

Analytics

The template includes a privacy-friendly analytics pattern using data-* attributes. Add tracking to any element:

<!-- Track CTA clicks -->
<a href="/pricing" data-track-cta="Get Started" data-track-section="hero">
  Get Started
</a>

<!-- Track form interactions (start, progress, submit, abandon) -->
<form data-track-form="contact">...</form>

<!-- Track content engagement (2s dwell time) -->
<section data-track-content="pricing" data-content-type="section">...</section>

Works with PostHog out of the box, or adapt to your analytics provider. No cookies required for basic tracking.

Security

Security headers are configured in public/_headers and applied automatically on Cloudflare:

  • Content Security Policy — Restricts script/style sources, prevents XSS
  • X-Frame-Options: DENY — Prevents clickjacking
  • X-Content-Type-Options: nosniff — Prevents MIME sniffing
  • Referrer-Policy — Controls referrer information
  • Permissions-Policy — Disables unused browser APIs

Fonts are self-hosted at build time, so no external font domains are needed in the CSP. The policy is pre-configured for PostHog and Cloudflare analytics. Modify _headers if you add other third-party scripts.

Deployment

Cloudflare Workers (Recommended)

The template includes preview and production environments out of the box. Deploys are manual — pushing to your default branch does not ship anything.

  1. Update wrangler.toml with your project name and domains
  2. Deploy:
bunx wrangler login

just preview       # deploy a preview build
just preview-down  # delete the preview when you are finished with it
just deploy        # deploy to production

Your site is live on Cloudflare's global edge network (300+ locations).

Use the just recipes rather than calling wrangler deploy directly. They apply two safeguards that a bare deploy skips.

Previews are built unindexable. A preview is a complete public copy of your site, so just preview builds it with PUBLIC_SITE_ENV=preview, which emits noindex, nofollow in the page head, adds an X-Robots-Tag header covering every response, and drops the production sitemap from robots.txt. Crawling itself stays allowed, deliberately — a blanket Disallow: / would stop crawlers ever reading the noindex directive. Production never sets that variable and keeps its normal index directives.

Previews do not record analytics. The same PUBLIC_SITE_ENV=preview build leaves the PostHog snippet out entirely, so reviewing a preview, or submitting a test form on it, never lands in your production analytics. just preview also fails if the built output still contains the snippet. To check tracking end to end, use the production site.

Take previews down with just preview-down once you are done. A preview left running is a second copy of your site competing with it in search.

Deploys refuse to run without an analytics key. If PUBLIC_POSTHOG_KEY is missing, both just preview and just deploy stop before building, and a production build throws rather than shipping a site that silently records nothing. This matters most in a git worktree, which does not carry your .env.

Deploys also check the built site. After building, just deploy confirms the output contains the PostHog snippet and the key the build was given, and refuses to deploy otherwise. That catches a build that succeeds but drops tracking, such as one made with PUBLIC_SITE_ENV=preview left set in your shell or .env.

Commands

Command Description
just install Install dependencies
just dev Start dev server at localhost:4321
just build Build for production
just check Build, then run tests
just preview-local Serve the production build locally
just preview Deploy an unindexable preview
just preview-down Delete the preview
just deploy Deploy to production

Run just with no arguments to list every recipe. Each one wraps the equivalent bun or wrangler command.

Tech Stack

License

MIT License — see LICENSE

Credits

Built by SocialTide — helping businesses build digital presences that work.

Read the why →


Want us to build your site? Get in touch for a free consultation.

About

Own your foundation. A production-ready template for the modern business.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages