Starter project
The FM Solo Starter is a reference Astro project built to the Solo contract. If you start from it, solo:validate passes on the first run.
What it includes
The starter is a minimal but realistic Astro project with:
- A
Base.astrolayout with global stylesheet loading - A set of Solo-friendly components such as
Hero,Section,CTA,Footer,GalleryItem,ImageGallery,ContactDetails, andContactForm - SEO components (
SEOPage,SEOWebsite,SEOOrganisation,SEOLocalBusiness,SEOArticle) on the blessed support list - Multiple example pages — including
index.astro,contact.astro,showcase.astro,styling.astro, and404.astro - A structured styling layer with
src/styles/styles.scssand partials undersrc/styles/partials/ - A small JS entrypoint under
src/scripts/for progressive enhancement - Static images served from
public/images/
Getting the starter
git clone https://github.com/withfrontmatter/fm-solo-starter cd frontmatter-solo-starter npm install
The starter is also included in the Solo CLI package download, so you can use the same reference project whether you start from GitHub or from the purchased archive.
Running solo-check on the starter
The starter should pass validation out of the box:
npx @withfrontmatter/solo-check --root . # Expected: exit 0, no errors
Styling and frontend workflow
The starter ships with SCSS by default, but it is not locked to SCSS.
- Source styling lives in
src/styles/styles.scss - Design structure is split into partials under
src/styles/partials/ - In development, Astro serves the source stylesheet directly for native hot reload
- In build, the starter emits stable assets under
public/assets/for backend handoff - JavaScript source lives under
src/scripts/withmain.jsas the entrypoint
If your team prefers plain CSS, you can switch the starter to plain CSS and keep the same Solo component contract. The styling system is a default authoring choice, not a hard requirement.
Component structure
Every component in the starter follows the same pattern — typed literal props, global CSS only, no dynamic expressions:
---
export interface Props {
headline: string; // required — literal string only
sub?: string; // optional
ctaLabel?: string; // optional
ctaHref?: string; // optional
}
const { headline, sub, ctaLabel, ctaHref } = Astro.props;
---
<section class="hero">
<h1>{headline}</h1>
{sub && <p>{sub}</p>}
</section> <Hero headline={page.title} /> fails with E201. The starter only uses string literals like <Hero headline="Hello Solo" />. See the Solo contract for the full rules.
Using the starter as a reference
If you're adapting an existing Astro project to the Solo contract, the starter is useful as a reference for:
- How to structure
Propsinterfaces - How to use SEO components correctly
- How to organize global styling and stable frontend assets
- How pages compose components without dynamic logic
- How to keep a frontend workflow comfortable while staying backend-friendly
What the starter does not include
The starter is intentionally minimal. It does not include:
- Framework components (React, Vue, Svelte) — these are skipped with placeholders
- Markdown pages — not supported in Solo v1
- Dynamic data fetching — by design
- CMS integration — that's the backend developer's responsibility