Example Site
A fully-working game guide site — every file, ready to copy. This is "Dungeon Delver
Guide", a fictional example that uses all the core @guides/ui components.
See the New Site Guide for scaffold instructions.
dungeon-delver-guide/
├── astro.config.mjs
├── package.json
├── tsconfig.json
├── wrangler.toml
├── src/
│ ├── layouts/
│ │ └── Layout.astro ← site branding lives here
│ └── pages/
│ ├── index.astro ← main page (hero, features, FAQ, download…)
│ ├── contact.astro
│ ├── thank-you.astro
│ └── privacy.astro
├── public/
│ ├── styles/global.css ← CSS variables (colours)
│ └── images/ ← your screenshot PNGs go here
│ ├── screen-1.png
│ └── …
└── functions/
└── api/
└── contact.ts ← Cloudflare Pages Function {
"name": "dungeon-delver-guide",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview"
},
"dependencies": {
"@guides/ui": "workspace:*",
"@guides/workers": "workspace:*",
"astro": "^5.7.0"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20240529.0"
}
} import { defineConfig } from 'astro/config';
import { createSitemap } from '@guides/ui/sitemap';
export default defineConfig({
output: 'static',
site: 'https://dungeon-delver-guide.pages.dev',
integrations: [createSitemap()],
vite: {
ssr: { noExternal: ['@guides/ui'] },
},
}); {
"extends": "astro/tsconfigs/base",
"compilerOptions": {
"types": ["@cloudflare/workers-types"]
}
} name = "dungeon-delver-guide"
pages_build_output_dir = "dist"
compatibility_date = "2024-09-23"
Define your colour palette here. Every @guides/ui component reads these
variables — changing --primary re-themes the whole site.
:root {
--primary: #b91c1c; /* deep red — brand colour */
--primary-dark: #991b1b;
--primary-light: #dc2626;
--accent: #f59e0b; /* amber highlight */
--accent-dark: #d97706;
--accent-light: #fcd34d;
--dark: #1c0a0a; /* hero / nav background */
--dark-mid: #2d1515;
--text: #1f2328;
--text-muted: #5a6270;
--surface: #f9f5f5;
--border: #e8dede;
--white: #ffffff;
}
The single source of truth for site-wide branding. The SiteConfig object
flows through to the nav, footer, OG tags, and theme-color meta tag.
---
import SiteLayout from '@guides/ui/SiteLayout.astro';
import type { SiteConfig } from '@guides/ui/SiteLayout.astro';
const config: SiteConfig = {
themeColor: '#b91c1c',
ogSiteName: 'Dungeon Delver Guide',
emoji: '⚔️',
brandName: 'Dungeon Delver Guide',
navCtaLabel: 'Get the app',
navCtaHref: '/app/',
footerTagline: 'Maps, bosses, loot, and every secret — all in one place.',
footerResources: [
{ label: 'Official Game Site', href: 'https://dungeondelver.example.com' },
{ label: 'Community Discord', href: 'https://discord.gg/example' },
{ label: 'Privacy Policy', href: '/privacy' },
],
copyright: '© 2026 Dungeon Delver Guide.',
};
interface Props {
title: string;
description: string;
canonical?: string;
keywords?: string;
noindex?: boolean;
variant?: 'default' | 'contact' | 'thanks';
}
const { title, description, canonical, keywords, noindex, variant = 'default' } = Astro.props;
---
<SiteLayout {config} {title} {description} {canonical} {keywords} {noindex} {variant}>
<slot name="head" slot="head" />
<slot />
</SiteLayout> The main page. Uses HeroSection, DownloadSection, Screenshots, and ContactForm. Add or remove sections as needed for your site.
---
import Layout from '../layouts/Layout.astro';
import HeroSection from '@guides/ui/HeroSection.astro';
import DownloadSection from '@guides/ui/DownloadSection.astro';
import Screenshots from '@guides/ui/Screenshots.astro';
import ContactForm from '@guides/ui/ContactForm.astro';
---
<Layout
title="Dungeon Delver Guide – Floors, Loot & Secrets"
description="The complete companion for Dungeon Delver. Maps, boss strategies, loot tables, and secret rooms."
canonical="https://dungeon-delver-guide.pages.dev/"
keywords="dungeon delver guide, dungeon delver tips, boss guide, loot tables"
>
<main>
<HeroSection
title="Dungeon Delver Guide"
subtitle="Your Complete Companion"
description="Maps, boss strategies, loot tables, and every secret room — all in one place."
>
<a href="/app/" class="cta-button">Open the App</a>
</HeroSection>
<section id="about" class="features">
<div class="container">
<h2>Everything you need</h2>
<div class="features-grid">
<div class="feature-card">
<span class="feature-icon">🗺️</span>
<h3>Interactive Maps</h3>
<p>Every floor mapped in detail. Mark rooms you've cleared and track your progress.</p>
</div>
<div class="feature-card">
<span class="feature-icon">⚔️</span>
<h3>Boss Strategies</h3>
<p>Step-by-step guides for every encounter — phases, weak points, and recommended gear.</p>
</div>
<div class="feature-card">
<span class="feature-icon">💎</span>
<h3>Loot Tables</h3>
<p>Drop rates, locations, and crafting recipes for every item in the game.</p>
</div>
<div class="feature-card">
<span class="feature-icon">🔍</span>
<h3>Secret Rooms</h3>
<p>All hidden rooms and their unlock conditions, including missable one-time rewards.</p>
</div>
</div>
</div>
</section>
<DownloadSection
heading="Get the Android App"
description="The full guide in your pocket, no internet required."
downloadUrl="https://github.com/you/dungeon-delver-guide/releases"
downloadAriaLabel="Download Dungeon Delver Guide APK"
downloadAlt="Download APK"
/>
<section id="faq" class="faq-section">
<div class="container">
<h2>Frequently asked questions</h2>
<div class="faq-grid">
<div class="faq-item">
<h3>Is the guide free?</h3>
<p>Yes — the website and Android app are completely free, with no ads or sign-ups required.</p>
</div>
<div class="faq-item">
<h3>How often is it updated?</h3>
<p>The guide is updated whenever the game receives new content or balance patches.</p>
</div>
<div class="faq-item">
<h3>Does the app work offline?</h3>
<p>Yes — once installed, the Android app works entirely offline. No internet needed.</p>
</div>
<div class="faq-item">
<h3>Can I contribute?</h3>
<p>Absolutely. Open a GitHub issue or use the contact form below to suggest corrections or additions.</p>
</div>
</div>
</div>
</section>
<Screenshots
title="Screenshots"
screenshots={[
{ src: '/images/screen-1.png', alt: 'Floor map view', caption: 'Interactive floor maps' },
{ src: '/images/screen-2.png', alt: 'Boss guide', caption: 'Detailed boss strategies' },
{ src: '/images/screen-3.png', alt: 'Loot table', caption: 'Full loot tables' },
{ src: '/images/screen-4.png', alt: 'Secret room list', caption: 'All secret rooms catalogued'},
]}
/>
<ContactForm webPageName="Dungeon Delver Guide" />
</main>
</Layout>
The variant="contact" prop on Layout renders ContactPage automatically.
No extra imports needed.
---
import Layout from '../layouts/Layout.astro';
---
<Layout
title="Contact – Dungeon Delver Guide"
description="Get in touch with the Dungeon Delver Guide team."
variant="contact"
/> ---
import Layout from '../layouts/Layout.astro';
---
<Layout
title="Message Sent – Dungeon Delver Guide"
description="Your message has been received."
variant="thanks"
/>
Update siteName, lastUpdated, and
localStorageDescription to match your site. The rest of the policy text
is pre-written and GDPR-friendly.
---
import Layout from '../layouts/Layout.astro';
import PrivacyPage from '@guides/ui/PrivacyPage.astro';
---
<Layout
title="Privacy Policy – Dungeon Delver Guide"
description="Privacy policy for Dungeon Delver Guide."
noindex={true}
>
<PrivacyPage
siteName="Dungeon Delver Guide"
lastUpdated="May 2026"
localStorageDescription="The app saves your progress (cleared rooms, bookmarks) locally on your device using the browser's local storage. This data never leaves your device."
thirdPartyLinks={[]}
/>
</Layout>
Cloudflare Pages Function that handles the contact form. The second argument to
handleContactForm is a label used to identify the form source in email
notifications.
import type { EventContext } from '@cloudflare/workers-types';
import { handleContactForm } from '@guides/workers/contact';
export const onRequestPost = (
context: EventContext<Record<string, unknown>, string, Record<string, unknown>>
) => handleContactForm(context.request, 'dungeon-delver-guide'); Ready to build? Follow the New Site Guide to scaffold the directory, register in the workspace, and deploy to Cloudflare Pages.
Browse the component library →