Archio Documentation
Introduction
Everything you need to know before you open your editor — what’s in the box, what it’s built with, and what it expects from your machine.
Welcome
Thanks for picking up Archio, a multi-page Astro theme for architecture studios, interior designers and building firms. It pairs a full-screen project slider, scroll-triggered reveals and a filterable portfolio with detailed project case studies, all built from plain .astro components, CSS and small vanilla JavaScript modules. This guide walks through installing the template, understanding how the project is organized, customizing content and styling, and shipping it to production. It’s written for developers who are comfortable with the command line but new to this specific codebase — if you already know Astro well, feel free to skip ahead using the sidebar.
What’s Included
Source files
The full, uncompiled project source — components, pages, nine Markdown project case studies, styles, scripts, and configuration.
Production build
Not shipped pre-built — run npm run build to generate a deployable dist/ folder in a few seconds (see Build & Preview).
Design assets
Demo photos and SVG icons in public/images/, a demo project film in public/videos/, Lottie icon animations in public/documents/, and the self-hosted Satoshi font in public/fonts/. No Figma file is included.
This documentation
A single offline HTML file — open it directly in any browser, no server required.
Features
- Pages for Home, About, Services, Work (filterable by category) and Contact, plus nine project case studies, three category pages, and Licensing and Changelog pages
- Projects managed as Markdown in an Astro content collection — add a file and its case-study page, portfolio card, and category listing appear automatically
- GSAP + ScrollTrigger scroll reveals, image reveals, rotating badges, a marquee and a vertical word loop, all respecting
prefers-reduced-motion - Swiper-powered hero fade slider, team and testimonial carousels, and a cross-fading quote slider, plus a video lightbox
- Lottie-animated hamburger and arrow icons via
lottie-web - Accessible by default: skip link, keyboard-operable menu, tabs, sliders and lightbox, labelled form fields, visible focus states
- Per-page title, description, canonical URL, Open Graph and Twitter tags, plus a sitemap from
@astrojs/sitemap
Technology Stack
Archio is a plain Astro project — no TypeScript source files, no UI framework, and no CSS preprocessor. Interactivity comes from small vanilla JavaScript modules using these libraries:
Requirements
| Tool | Minimum version | Notes |
|---|---|---|
| Node.js | 22.12.0 or later | Set by engines.node in package.json; LTS releases are recommended |
| Package manager | npm 9+, pnpm 8+, or Yarn 1.22+ | A package-lock.json ships, so npm installs the exact tested versions; examples below cover all three |
| Code editor | — | VS Code with the Astro extension (recommended in .vscode/extensions.json) is a comfortable default |
| Git | 2.x | Only required if you plan to version-control your customized copy |
Browser Support
The built site targets the last two versions of all evergreen browsers:
Internet Explorer 11 is not supported. The template ships no polyfills.
Getting Started
From a downloaded ZIP to a running dev server in five steps.
Installation & Extraction
- Download the template ZIP from your purchase confirmation email or account downloads page.
- Extract it to a folder on your machine — avoid folder names with spaces or special characters.
- Open that folder in your terminal and in your code editor.
# Extract on macOS / Linux
unzip archio-architecture-astro-package.zip
cd archio-architecture-astro-package/archio-architecture-astro
Node.js Setup
Check which version of Node.js is currently active:
node --version
# v22.12.0 or later
If you manage multiple Node versions, tools like nvm or fnm make switching painless:
nvm install 22
nvm use 22
Install Dependencies
From the project root, install packages with your preferred package manager:
npm install
pnpm install
yarn install
This reads package.json and downloads every dependency into a local node_modules/ folder. It only needs to be re-run when dependencies change.
Run the Development Server
npm run dev
pnpm dev
This starts Vite’s local dev server with hot module reloading — edits to components, pages, and styles appear in the browser immediately without a manual refresh. By default it’s available at http://localhost:4321; the terminal output will confirm the exact address.
Build for Production & Preview
# Compile an optimized production build into dist/
npm run build
# Serve that build locally to sanity-check it
npm run preview
build validates the project content collection, renders every route (including each project and category page), bundles and minifies CSS/JS, and writes static output plus sitemap-index.xml to dist/. preview serves that exact output locally so you can verify it before deploying — it does not rebuild automatically, so re-run build after further changes.
Use dev while you’re customizing the template. Use build, then preview, once before you deploy — it catches issues (like a missing import or a project Markdown file with an invalid frontmatter field) on pages you may not have opened during development.
Project Structure
A tour of the folders you’ll actually touch, and the ones you generally shouldn’t.
| Path | Purpose |
|---|---|
public/ | Files here are copied to the output root untouched — no optimization or hashing. In Archio this holds every image, the favicon (images/favicon.png), the demo video, the Lottie JSON files, and the Satoshi font. |
src/components/ | Shared pieces (Navbar, Footer, EnquiryForm, ProjectCard, TeamSlider, OurWork, SliderArrows, VideoLightbox) at the top level, and page sections grouped in home/, about/, services/, work/, contact/, and template-info/. |
src/content/projects/ | The nine project case studies as Markdown files. Each file’s frontmatter is validated against the schema in src/content.config.js. |
src/layouts/ | BaseLayout.astro — the shared page shell: stylesheets, <head> SEO tags, fonts, navbar, footer, and the video lightbox. |
src/lib/ | projects.js exports getProjects() (sorted by order), the categories list, and slugify(). |
src/pages/ | Every file here becomes a route automatically. See Pages for details. |
src/scripts/ | Vanilla JS modules: reveal.js (scroll reveals), hover-effects.js, lottie.js, and peek-loop-slider.js (infinite Swiper carousels). |
src/styles/ | Global stylesheets and CSS variables. See Styling. |
.gitignore (ignores dist/, .astro/, node_modules/ and .env files) and .vscode/ (recommended Astro extension and a launch config). Folders such as node_modules/, .astro/ and dist/ are generated when you install, run, or build the project.
Configuration
The files that control how the project builds, and where to set site-wide values.
package.json
Defines dependencies and the scripts you run from the terminal (dev, build, preview). Add your own script here if you introduce a new tool.
{
"name": "archio-architecture-astro",
"type": "module",
"version": "0.0.1",
"engines": { "node": ">=22.12.0" },
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/sitemap": "^3.7.4",
"astro": "^7.3.5",
"gsap": "^3.15.0",
"lottie-web": "^5.13.0",
"swiper": "^14.3.0"
}
}
astro.config.mjs
Controls integrations, the deployed site URL, and build behavior. Archio registers a single integration, @astrojs/sitemap, and keeps the default static output. Set site to your real domain — canonical links, Open Graph image URLs, and the sitemap are all built from it.
import { defineConfig } from "astro/config";
import sitemap from "@astrojs/sitemap";
export default defineConfig({
// Replace with your production URL. It is used for canonical links, Open Graph images and the sitemap.
site: "https://example.com",
integrations: [
sitemap({
filter: (page) => !page.includes("/template-info/"),
}),
],
});
content.config.js
Defines the projects content collection: every Markdown file in src/content/projects/ is loaded and its frontmatter validated against this schema. Add a field here before using it in a project file.
const projects = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/projects" }),
schema: z.object({
title: z.string(),
order: z.number(),
category: z.enum(["Residential", "Commercial", "Hospitality"]),
estimated: z.string(),
thumbnail: z.string(),
image: z.string(),
video: z.string().optional(),
address: z.string(),
client: z.string(),
type: z.string(),
location: z.string(),
services: z.array(z.string()),
featured: z.boolean().default(false),
seoTitle: z.string().optional(),
seoDescription: z.string().optional(),
}),
});
tsconfig.json
Archio’s source is plain JavaScript, so this file only gives your editor Astro’s type information (including the generated content-collection types). It defines no path aliases — imports use relative paths such as ../components/Navbar.astro.
{
"extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"]
}
Environment Variables (.env)
Archio doesn’t read any environment variables out of the box, so no .env file is needed. If you add one later for values that differ between environments (API URLs, keys) or shouldn’t be committed to Git, create it in the project root. Variables must be prefixed PUBLIC_ to be readable in client-side code.
# Exposed to the browser — never put secrets here
PUBLIC_SITE_URL=https://example.com
# Server-only — safe for secrets, not readable in browser code
API_SECRET_KEY=your_secret_key
Add .env to .gitignore (it usually is by default). Anything without the PUBLIC_ prefix should stay off the client entirely.
Pages
How routes are created, which pages ship with Archio, and how project pages are generated.
Creating a New Page
Astro uses file-based routing: any .astro or .md file placed in src/pages/ automatically becomes a route matching its file path. Archio ships these routes:
src/pages/index.astro → /
src/pages/about.astro → /about
src/pages/services.astro → /services
src/pages/work.astro → /work (filterable portfolio)
src/pages/contact.astro → /contact
src/pages/project/[slug].astro → /project/:slug (one per project, dynamic)
src/pages/category/[slug].astro → /category/residential | commercial | hospitality
src/pages/template-info/licensing.astro → /template-info/licensing
src/pages/template-info/changelog.astro → /template-info/changelog
To add a page, create a new file in src/pages/ using the layout and structure of an existing, similar page as a starting point:
---
import BaseLayout from "../layouts/BaseLayout.astro";
import EnquiryForm from "../components/EnquiryForm.astro";
---
<BaseLayout title="Careers | Archio" description="Join our studio.">
<h1 class="page-title">Careers</h1>
<EnquiryForm variant="contact" />
</BaseLayout>
Editing an Existing Page
Archio’s page files are short — they import BaseLayout and a list of section components. For example, src/pages/index.astro is just HomeHero, HomeAbout, NumberSection, FeaturedWork, Approach, TeamSlider, SingleTestimonial and EnquiryForm. To change a section’s text or images, open its component in src/components/<page>/; to reorder or remove a section, edit the page file.
Dynamic Routes
Files wrapped in square brackets, such as [slug].astro, generate multiple pages from a single template. Archio uses this for project case studies and category listings. Astro requires a getStaticPaths() function for these on statically-generated sites — here is the real one from the project page, which also wires up the previous/next project links:
---
import { render } from "astro:content";
import { getProjects } from "../../lib/projects.js";
export async function getStaticPaths() {
const projects = await getProjects();
return projects.map((project, i) => ({
params: { slug: project.id },
props: {
project,
prev: projects[(i - 1 + projects.length) % projects.length],
next: projects[(i + 1) % projects.length],
},
}));
}
---
A project’s URL slug is its Markdown filename — src/content/projects/costa-blanca.md becomes /project/costa-blanca.
Layouts
Layouts (in src/layouts/) wrap page content with shared structure — the <html> shell, <head> metadata, header, and footer. Every Archio page renders inside BaseLayout.astro via a <slot /> (simplified here):
---
import "../styles/archio.css"; // plus normalize, base-framework, overrides
import Navbar from "../components/Navbar.astro";
import Footer from "../components/Footer.astro";
const { title, description, ogImage, navVariant = "dark", noindex = false } = Astro.props;
---
<html lang="en">
<head><title>{title}</title> <!-- + SEO, fonts, favicon --></head>
<body>
<Navbar variant={navVariant} />
<main id="main">
<slot /> <!-- page content is injected here -->
</main>
<Footer />
</body>
</html>
Page Metadata & the 404 Page
BaseLayout accepts title, description, ogImage (defaults to /images/og-image.webp), navVariant ("light" for pages with a dark hero, such as Home and About; "dark" otherwise) and noindex. Pass a unique title and description on every page for correct browser tabs and search results (see also SEO). Archio doesn’t ship a custom 404 page — your host’s default is shown. To add one, create src/pages/404.astro; Astro serves it automatically whenever no route matches.
Components
The building blocks pages are assembled from, and how data flows into them.
Reusable Components
Components live in src/components/ and encapsulate one piece of UI so it can be reused across pages without copy-pasting markup. Every Archio component is an .astro file:
| Component | Used on / purpose |
|---|---|
Navbar, Footer | Every page, via BaseLayout |
VideoLightbox | Every page, via BaseLayout; opens any link with a data-video attribute (a video file URL or a YouTube video id) |
EnquiryForm | Home and Contact enquiry form |
ProjectCard | Project tile on Home, Work, and category pages |
TeamSlider, OurWork, SliderArrows | Team carousel (Home, About), the work-with-video teaser (About, Services), and the shared slider arrow buttons |
home/ | HomeHero, HomeAbout, NumberSection, FeaturedWork, Approach, SingleTestimonial |
about/ | AboutHero, Story, Achievement, Expertise, CoreValues |
services/ | ServicesHero, WhatWeDo, WhyUs, Testimonials |
work/, contact/ | WorkProjects (tabbed portfolio), ContactHero |
template-info/ | LicensingContent, ChangelogContent |
Props
Props are the inputs a component accepts, similar to HTML attributes. Archio components read them by destructuring Astro.props with default values — there are no TypeScript interfaces, so the defaults in the frontmatter are the documentation. EnquiryForm is a good example:
---
/**
* Enquiry form. The "home" variant shows the phone/email links, "contact" shows the rotating star.
* Set `action` to your form endpoint (Formspree, Netlify Forms, your own API…).
*/
const { variant = "home", action = "#" } = Astro.props;
---
In plain language: variant is optional and switches the side panel between the phone/email links ("home") and a rotating star ("contact"); action is optional and, if omitted, the form runs in demo mode and just shows its success message. Other components with props: Navbar (variant: "light" or "dark") and ProjectCard (project, coverClass, imageAlt).
Component Composition
Larger sections are usually composed from smaller components rather than written as one long block of markup. The category page, for instance, renders a ProjectCard for every project in that category:
{projects.map((project) => (
<div role="listitem" class="all-projects-collection-item">
<ProjectCard project={project} coverClass="cream-bg" imageAlt={project.data.title} />
</div>
))}
Passing Data to Components
In Astro, props are passed the same way as HTML attributes and read via Astro.props:
---
import EnquiryForm from "../components/EnquiryForm.astro";
---
<EnquiryForm variant="contact" action="https://formspree.io/f/your-id" />
Archio uses no UI framework. Components render static HTML, and anything interactive — the menu, sliders, tabs, lightbox, scroll reveals — is a small vanilla JavaScript module in the component’s own <script> tag or in src/scripts/, using GSAP, Swiper, and lottie-web. Astro bundles these scripts automatically.
Styling
Where to change colors, type, and spacing without fighting the build.
Global Styles & CSS Variables
Archio is styled with plain CSS — no Tailwind, no Sass. BaseLayout.astro imports four global stylesheets in this order: normalize.css, base-framework.css (layout and utility classes), archio.css (the theme), and overrides.css (small fixes layered on top). The brand palette and font families are CSS custom properties at the top of src/styles/archio.css. Change a value here and it updates across the whole site.
:root {
--fonts--body: "Satoshi Variable", sans-serif;
--colors--body: #616377;
--colors--heading: #1c203a;
--colors--white: white;
--fonts--heading: Outfit, sans-serif;
--colors--yellow: #e0a211;
--colors--cream: #fff7ed;
--colors--black: black;
}
--colors--yellow is the accent used on buttons, the menu button, and highlights; --colors--cream is the warm section background.
Component Styles
Astro components support scoped <style> blocks — CSS written there only applies to that component, so class names never collide across files. Most of Archio’s styling lives in the global stylesheets above, but a few components (HomeHero, NumberSection, Story, CoreValues, SliderArrows) carry small scoped blocks like this one:
<style>
.arrow-line {
display: block;
}
</style>
Responsive Design, Typography & Spacing
The heading and body type scale is set on the element and class selectors in archio.css, with desktop-first breakpoints at max-width: 991px (tablet), 767px (landscape phone), and 479px (phone). Prefer adjusting these shared rules over overriding sizes on individual elements, so the site keeps a consistent rhythm as you edit it.
The dist/ folder is generated output — any change made there is overwritten on the next build. Always edit files under src/.
Images & Assets
Where Archio keeps its static files, and how to swap them for your own.
Archio serves every asset from public/ — there is no src/assets/ folder. Files there are copied to the build output as-is and referenced by root-relative URLs such as /images/og-image.webp.
| Location | Contains | Referenced from |
|---|---|---|
public/images/ | Page photos (WebP), SVG icons and logos, favicon.png, webclip.png, og-image.webp | Component markup and BaseLayout |
public/images/projects/ | Project thumbnails, main images, and inner images | Project Markdown frontmatter and body |
public/videos/ | project-film.mp4 demo film (Pexels stock footage) | data-video links opened by VideoLightbox |
public/documents/ | Lottie JSON animations | data-lottie attributes |
public/fonts/ | Satoshi-Variable.ttf | @font-face in archio.css |
Replacing Images
Swap the file in place (keeping the same filename) or update the path to point at your new file. In components, images are plain <img> tags; for projects, the paths sit in each Markdown file’s frontmatter:
thumbnail: "/images/projects/thumb-5.webp" # card on Home, Work, category pages
image: "/images/projects/project-main.webp" # case-study hero + og:image
video: "/videos/project-film.mp4" # optional
Supported Formats & SVGs
The demo photos are WebP, and icons and logos are SVG files referenced as plain <img> sources (a few small icons, such as the social links and slider arrows, are inline <svg> markup inside their components). Any format the browser can display — JPEG, PNG, WebP, AVIF, GIF, SVG — works in public/.
Image Optimization
Because the images live in public/, the build does not resize or re-encode them. Compress and size your replacements before adding them (WebP at roughly the dimensions of the image you’re replacing is a good target). If you want build-time optimization, you can move an image into src/ and render it with Astro’s <Image /> component from astro:assets instead.
Keep the same filename when you can — then nothing else needs editing. The licensing page (/template-info/licensing) lists the sources of the demo photos and video; replace them with your own before going live.
Fonts & Icons
Swapping typefaces and icon sets without touching every component.
Google Fonts
Archio uses two typefaces: Outfit for headings (--fonts--heading) and Satoshi for body text (--fonts--body). Outfit is loaded from Google Fonts by a <link> tag in the shared layout’s <head>. To change it, replace that link with your chosen font’s embed code, then update --fonts--heading in archio.css. A few rules in archio.css name Outfit, sans-serif directly instead of using the variable, so search the file for Outfit as well.
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap" rel="stylesheet" />
Local Fonts
Satoshi (from Fontshare) is self-hosted as a variable font in public/fonts/Satoshi-Variable.ttf, declared with @font-face at the top of archio.css, and preloaded from BaseLayout. To swap it, drop your font file into public/fonts/, update the src URL and family name here, and change the <link rel="preload"> path in the layout:
@font-face {
font-family: Satoshi Variable;
src: url('/fonts/Satoshi-Variable.ttf') format("truetype");
font-weight: 300 900;
font-style: normal;
font-display: swap;
}
Icon Libraries
Archio doesn’t use an icon library or icon components. Its icons come in three forms:
- SVG files in
public/images/(e.g.Interior-Design.svg,Awards.svg,Star.svg,Quote.svg), referenced with<img>tags. - Inline
<svg>markup for small UI icons such as the social links, slider arrows, and close buttons, written directly in their components. - Lottie animations in
public/documents/for the animated hamburger and arrow icons, loaded bysrc/scripts/lottie.jsinto any element carrying adata-lottie="/documents/…json"attribute.
Replacing & Adding Icons
To replace an SVG icon, overwrite the file in public/images/ with the same name, or point the <img src> at a new file. Inline SVGs can be swapped by pasting new <svg> markup into the component. To change a Lottie animation, export a new JSON file (e.g. from LottieFiles), place it in public/documents/, and update the data-lottie path.
Content Editing
The fastest, lowest-risk way to make the site say what you want it to say.
Everything in this section is plain text or attribute changes — no logic to break. Save the file, and your dev server (from Getting Started) will refresh the browser automatically so you can see the change right away.
Headings, Paragraphs & Buttons
Page text lives in the section components, not the page files. Find the section in src/components/<page>/, locate the text between the tags, and edit it directly. Keep the existing class attributes — classes like slide-in-from-bottom-100ms drive the scroll-reveal animation:
<!-- before -->
<h1 class="page-title white-font-color slide-in-from-bottom-100ms">Crafting exquisite architectural and interior designs</h1>
<!-- after -->
<h1 class="page-title white-font-color slide-in-from-bottom-100ms">Designing calm, light-filled homes</h1>
Navigation & Footer
Header menu links are a small links array at the top of src/components/Navbar.astro. Footer link columns and social icons are written directly in src/components/Footer.astro. See Navigation for the full pattern.
Sliders, Team & Testimonials
Repeating content blocks are driven by an array at the top of their component rather than hand-written per card, so adding or removing an item is a matter of editing the list. The arrays are slides in home/HomeHero.astro, team in TeamSlider.astro, testimonials in home/SingleTestimonial.astro and services/Testimonials.astro, and values in about/CoreValues.astro:
const team = [
{ name: "Phoenix Smith", role: "CEO & Head Architect", image: "/images/1.webp" },
{ name: "Peter Smith", role: "Project Manager", image: "/images/4.webp" },
{ name: "Sofia Woods", role: "Interior Designer", image: "/images/2.webp" },
{ name: "Anthony Green", role: "Senior Architect", image: "/images/3.webp" },
];
Projects & Contact Information
Archio has no blog; its long-form content is the project case studies. Each one is a Markdown file in src/content/projects/ — edit the frontmatter (title, category, client, location, images, featured, order) and the body directly, or copy a file to add a new project. Its case-study page, portfolio card, and category listing appear automatically. The first six projects with featured: true appear in the home page’s featured work, and order sets their position in every list.
The placeholder contact details (hello@example.com, phone numbers, social links) are repeated in a few components, so update each of them: Navbar.astro (header and slide-in menu), contact/ContactHero.astro, EnquiryForm.astro (the “home” variant’s phone/email links), and Footer.astro (social icons).
Forms
What ships out of the box, and what still needs a backend.
Archio’s enquiry form captures input in the browser, but submitting it to an email inbox, database, or mailing list requires a backend endpoint or a third-party service — this is not included by default. The template is not wired to any specific service: until you pass an endpoint, the form runs in demo mode and only shows its success message.
Contact Forms
The enquiry form (src/components/EnquiryForm.astro) appears on the Home and Contact pages and collects first and last name, email, phone number, service, budget, and a message. To connect it, pass your endpoint as the action prop wherever the form is used; the form then submits as a normal POST to that URL:
<!-- before: demo mode -->
<EnquiryForm variant="contact" />
<!-- after: real submissions -->
<EnquiryForm variant="contact" action="https://formspree.io/f/your-id" />
Do the same in src/pages/index.astro for the home page form. The “Service looking for” and “Budget” dropdowns ship with placeholder options (“First choice”, “Second choice”…); edit the <option> tags in EnquiryForm.astro to match your services and price bands.
Newsletter Forms
Archio doesn’t include a newsletter signup form, so no email provider is pre-wired. If you add one, a provider’s embedded form (Mailchimp, ConvertKit, etc.) can be pasted into any component.
Form Validation
Required fields and email format are checked in the browser before submission using standard HTML attributes (required, type="email", maxlength), giving users immediate feedback without a round trip to a server. Validate again on whatever service receives the submission.
Third-Party Form Services
If you’d rather not run your own backend, services like Formspree, Getform, or Basin accept form submissions directly from static HTML and forward them to your email — typically a one-line change to the form’s action attribute.
API & Data
Archio fetches no data from an external API — all content is local. The examples below only apply if you add one.
Project data comes from the local projects content collection, read at build time through getProjects() in src/lib/projects.js. Every other piece of content is written directly in the components. No API keys, environment variables, or network requests are involved in building the site.
API Configuration
If you connect an API, read its URLs and keys from environment variables (see Configuration) rather than hard-coding them, so the same code can point at a staging or production API depending on environment:
PUBLIC_API_URL=https://example.com/api
PUBLIC_API_KEY=your_api_key
The values above are placeholders. Keep real API keys out of version control, and prefer server-only variables (without the PUBLIC_ prefix) for anything sensitive.
Fetch Requests
const res = await fetch(`${import.meta.env.PUBLIC_API_URL}/products`, {
headers: { Authorization: `Bearer ${import.meta.env.PUBLIC_API_KEY}` },
});
const data = await res.json();
Data Structures
Archio’s one structured data type is a project entry. Each item returned by getProjects() has an id (the filename, used as the URL slug), a body (the Markdown content, rendered with render() from astro:content), and a data object with the fields defined in src/content.config.js (see Configuration):
{
id: "classic-villa",
data: {
title: "Classic Villa", order: 5, category: "Residential",
estimated: "Est. 2019 — 20", thumbnail: "/images/projects/thumb-5.webp",
image: "/images/projects/project-main.webp", video: "/videos/project-film.mp4",
address: "123 Design Avenue, Springfield, USA", client: "John Carter",
type: "Luxury Villa", location: "New York, NY",
services: ["Architecture", "Interior", "Planning"],
featured: true, seoTitle: "…", seoDescription: "…"
}
}
If you replace the Markdown files with data from a headless CMS, have getProjects() map its response onto this same shape so the pages and components that read project.data keep working. The project page renders Markdown bodies with render(), so it needs adjusting if your CMS returns HTML instead.
Error Handling
try {
const res = await fetch(apiUrl);
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
} catch (err) {
// show a fallback UI state instead of a blank page
console.error(err);
}
SEO
Per-page metadata, social previews, and the machine-readable files search engines expect.
Page Title & Meta Description
Pass a unique title and description into the layout on every page — these drive both the browser tab and the snippet shown in search results. The home page passes none, so it falls back to the defaults in BaseLayout.astro; project pages use each project’s seoTitle and seoDescription frontmatter.
<BaseLayout
title="About | Archio"
description="Crafting exquisite architectural and interior designs"
ogImage="/images/story-image_1.webp"
navVariant="light"
>
Canonical URL, Open Graph & Twitter/X Cards
Set inside BaseLayout’s <head>, using the site value from astro.config.mjs to build absolute URLs. The og:image defaults to /images/og-image.webp and can be overridden per page with the ogImage prop:
---
const canonical = new URL(Astro.url.pathname, Astro.site ?? Astro.url);
const ogImageUrl = new URL(ogImage, Astro.site ?? Astro.url);
---
<link rel="canonical" href={canonical} />
<meta property="og:type" content="website" />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={ogImageUrl} />
<meta name="twitter:card" content="summary_large_image" />
{noindex && <meta name="robots" content="noindex" />}
Sitemap & Robots.txt
Archio uses Astro’s official @astrojs/sitemap integration, which generates sitemap-index.xml automatically at build time from the site value. The /template-info/ pages are filtered out of the sitemap and also carry a noindex tag. No robots.txt ships with the template — to add one, create public/robots.txt pointing to the sitemap:
User-agent: *
Allow: /
Sitemap: https://example.com/sitemap-index.xml
Structured Data & Semantic HTML
Use landmark elements (<header>, <nav>, <main>, <article>) and a single <h1> per page so both search engines and screen readers can parse the page’s structure. Archio’s layout already provides these landmarks (plus a skip link to <main id="main">), and every inner page has one <h1>. The home page has no <h1> — its hero slider titles are styled text — so consider adding one (it can be visually hidden) with your studio’s name and specialty. No JSON-LD structured data ships with the template; add it in BaseLayout’s <head> for rich results (e.g. Organization or LocalBusiness schema for your studio) where relevant.
Deployment
Platform-by-platform steps. Confirm your rendering mode first — it changes the build output you deploy.
A static Astro build (the default) produces plain HTML/CSS/JS in dist/ that any static host can serve. An Astro site using server-side rendering (SSR via an adapter) needs a Node-capable host or the platform’s matching adapter. Archio ships as a fully static site with no adapter, so the static instructions below apply unless you change that. Using the wrong instructions for your rendering mode is the most common deployment mistake.
Vercel
- Push the project to a GitHub, GitLab, or Bitbucket repository.
- In Vercel, choose Add New → Project and import that repository.
- Build command:
npm run build· Output directory:dist(Astro static) — Vercel’s Astro preset detects this automatically in most cases. - If you’ve added a
.envfile, add its variables under Project Settings → Environment Variables (Archio needs none by default). - Click Deploy.
Netlify
[build]
command = "npm run build"
publish = "dist"
Connect the repository in the Netlify dashboard, confirm these build settings, add environment variables under Site configuration → Environment variables, and deploy.
Cloudflare Pages
Connect the repository, set the build command to npm run build and the output directory to dist. For SSR Astro sites, use the official @astrojs/cloudflare adapter instead of the static preset.
GitHub Pages
Set site and base in astro.config.mjs to match your repository URL, then build and publish the dist/ folder to the gh-pages branch (via the official astro build + a deploy action, or manually). GitHub Pages only serves static output — it cannot run an SSR adapter.
Traditional Hosting
For a static build, upload the contents of dist/ to your host’s public web root via FTP/SFTP or your host’s file manager. If you later switch to an SSR build that needs a Node process, the host must support running node continuously (a VPS or a Node-compatible host) — plain shared hosting without Node support cannot run it.
Build & Production
What happens when you run build, and a checklist before you ship.
npm run build # render every route, bundle, and write dist/
npm run preview # serve dist/ locally, exactly as it will run in production
Build Output
The build writes static HTML for every page (including one per project and per category), hashed CSS/JS bundles, the sitemap, and a copy of everything in public/ to dist/. This folder is disposable and regenerated by every build — Archio’s .gitignore already keeps it out of Git.
Environment Variables in Production
Archio needs no environment variables out of the box. If you add some, remember that variables from your local .env are not deployed automatically — each hosting platform requires you to set them again in its dashboard (see Deployment). A missing production variable is one of the most common causes of a build that works locally but fails, or behaves unexpectedly, once deployed.
Production Checklist
- Run
npm run buildlocally and confirm it completes with no errors. - Run
npm run previewand click through the main pages. - Confirm the
siteURL inastro.config.mjsmatches your real domain. - If you added a
.envfile, set each of its variables in your hosting platform’s dashboard. - Pass a real
actionendpoint to both<EnquiryForm>usages (Home and Contact) so the form stops running in demo mode. - Replace the placeholder
hello@example.com, phone numbers, and social links in the Navbar, Contact hero, Enquiry form, and Footer. - Verify favicon (
public/images/favicon.png), Open Graph image (public/images/og-image.webp), and the default title/description inBaseLayout.astroare your own, not the template defaults. - Replace the demo photos and project film, and decide whether to keep the
/template-info/Licensing and Changelog pages and their footer links.
Troubleshooting
The most common problems, in the order you’re likely to hit them.
npm install fails
- Cause
- Node.js version too old, a corrupted local cache, or a stale lockfile from a different package manager.
- Solution
- Confirm
node --versionmeets the requirement in Requirements, then runrm -rf node_modules package-lock.json && npm install.
Port already in use
- Cause
- Another process (often a previous dev server that didn’t shut down cleanly) is already listening on the default port.
- Solution
- Stop the other process, or start this one on a different port:
npm run dev -- --port 4322.
Module not found
- Cause
- A missing dependency, or a typo in a relative import path (Archio uses no path aliases).
- Solution
- Re-run
npm install; check the relative path (../vs../../) and that its casing matches the file exactly — macOS and Windows tolerate case mismatches that Linux build servers don’t.
Images not loading
- Cause
- A wrong path, or a path that includes
public/. Archio’s images live inpublic/, which is served from the site root.
- Solution
- Review Images & Assets — use a root-relative URL like
/images/Logo-Dark.svg(not/public/images/…), and check the filename’s exact casing.
Styles not loading
- Cause
- A new page doesn’t render inside
BaseLayout(which imports all four stylesheets), or the stylesheet import order was changed.
- Solution
- Wrap the page in
<BaseLayout>; keep the imports inBaseLayout.astroin order:normalize.css,base-framework.css,archio.css,overrides.css.
Content collection errors
- Cause
- A project Markdown file’s frontmatter doesn’t match the schema in
src/content.config.js— a missing required field, a misspelled key, or acategoryother than Residential, Commercial, or Hospitality.
- Solution
- Read the error’s file name and field, compare the frontmatter against the schema (see Configuration), and fix whichever side is wrong. To add a new category, add it to both the
z.enumin the schema and thecategoriesarray insrc/lib/projects.js.
Animations or sliders not running
- Cause
- Your operating system has “reduce motion” enabled (Archio deliberately skips its reveal animations then), or a required class /
data-attribute was removed while editing markup.
- Solution
- Check the browser console for errors first. Keep reveal classes such as
slide-in-from-bottom-100msand attributes such asdata-lottie,data-video, anddata-spinon the elements you edit.
Build fails (but dev server works)
- Cause
- The dev server only renders the pages you open, while
buildrenders every route, including each project and category page — an error on a page you never visited during development surfaces only at build time.
- Solution
- Read the full terminal output for the first error (later errors are often side effects of it); fix issues top to bottom and re-run.
Environment variables not working
- Cause
- Only relevant if you’ve added a
.envfile (Archio uses none by default). Missing thePUBLIC_prefix for a client-side value, or the dev server wasn’t restarted after editing.env.
- Solution
- Rename the variable with the
PUBLIC_prefix if it’s used in browser code, then stop and restartnpm run dev— env changes aren’t hot-reloaded.
Deployment problems
- Cause
- Wrong output directory configured on the host, or environment variables set locally but not in the platform’s dashboard.
- Solution
- Re-check the build command and output folder against Deployment for your platform, and confirm every variable from
.envis duplicated there.
FAQ
Quick answers to the questions we hear most.
How do I install the template?
Extract the ZIP, run your package manager’s install command, then start the dev server. The full walkthrough is in Getting Started.
Which Node.js version should I use?
Node 22.12.0 or later — see Requirements. The current LTS release is a safe default.
Do I need to know TypeScript?
No. Archio is written in plain JavaScript inside .astro files and .js modules. The tsconfig.json only powers editor autocomplete; you can add TypeScript later if you want it.
How do I change colors?
Update the CSS custom properties (--colors--yellow, --colors--heading, …) at the top of src/styles/archio.css — see Styling.
How do I change fonts?
Swap the Google Fonts link (Outfit) or the self-hosted @font-face (Satoshi) and update the matching --fonts--heading / --fonts--body variable — see Fonts & Icons.
How do I replace images?
Overwrite the file in public/images/ with the same name, or update the path in the component or project frontmatter — see Images & Assets.
How do I add a new project?
Copy one of the Markdown files in src/content/projects/, rename it (the filename becomes the URL), and edit its frontmatter and body. Its case-study page, portfolio card, and category listing are created automatically — see Content Editing.
How do I add a new page?
Add a file to src/pages/; the route is created automatically — see Pages.
How do I make the contact form send emails?
Pass your form endpoint (Formspree, Getform, your own API…) as the action prop on <EnquiryForm> in both index.astro and contact.astro — see Forms.
How do I deploy the template?
Platform-specific steps for Vercel, Netlify, Cloudflare Pages, GitHub Pages, and traditional hosts are in Deployment.
Can I use the template commercially?
The demo photos come from Unsplash, Pexels, and Freepik (the Freepik image on the About and Contact pages requires attribution), the project film is Pexels stock footage, Outfit is from Google Fonts, and Satoshi is from Fontshare — see the template’s /template-info/licensing page. Replace the placeholder content with your own before publishing. [State your license terms here — e.g. standard vs. extended license — and link to the full license text.]
Where can I get support?
See the Support section for contact details and what to include in a request.
Changelog
Every notable change, newest first. Add a new entry above the last one for each release.
- AddedInitial release: Home, About, Services, Work, and Contact pages, nine project case studies in a Markdown content collection, three category pages, Licensing and Changelog pages, GSAP scroll animations, Swiper sliders, Lottie icons, the video lightbox, and the enquiry form.
Copy the markup for one entry above, update the version number, date, and bullet list, and place it at the top of this section for each new release.
Support
Stuck on something this guide didn’t cover? Here’s how to reach us.
Documentation
Most questions are answered somewhere in this guide — try the search (Ctrl K) before reaching out.
Back to topSupport hours
We’re based in India and available Monday–Friday, 10am–7pm IST. Expect a response within 24 hours.
What to Include in a Support Request
The fastest way to get a useful answer is to include the details below in your first message:
When contacting support, please include:
- Template name and version
- Browser (and version)
- Operating system
- Node.js version (node --version)
- The exact error message
- Steps to reproduce the problem