Skip to content

Starter Templates Since 3.5.0

Starters are pre-built site structures that give you a working site out of the box. Each one provides layouts, page templates, partials, a builder-pages collection, and page objects — everything needed for a working site immediately.

Terminal window
# List available starters
tcms builder:init --list
# Scaffold a business site (templates + pages + demo content)
tcms builder:init business
# Scaffold + Vite frontend in one go
tcms builder:init business --frontend

That’s it. There’s no generation step — the page router serves your routes dynamically from the collection data. Visit your site and pages render immediately.

After scaffolding, every starter ships with a /readme page (hidden from navigation by default) that walks you through the next steps in your browser. Delete it whenever you’re ready.

The simplest starting point — a single homepage with a clean layout.

Pages: Home

Files created:

tcms-data/builder/
layouts/default.twig
pages/index.twig
pages/readme.twig
partials/nav.twig
partials/footer.twig
public/assets/
style.css ← edit me

Best for: Starting from scratch with maximum flexibility.


A professional business website with multiple pages and a card-based layout.

Pages: Home, About, Services, Contact

Files created:

tcms-data/builder/
layouts/default.twig
pages/index.twig
pages/about.twig
pages/services.twig
pages/contact.twig
pages/readme.twig
partials/nav.twig
partials/footer.twig
public/assets/
style.css ← edit me

Features:

  • Hero section on homepage
  • Service cards in a responsive grid
  • Contact form template
  • Professional navigation with dynamic page links

Best for: Small business sites, agency sites, service providers.


A blog-focused site with post listing and individual post templates.

Pages: Home, Blog, Blog Post, About

Files created:

tcms-data/builder/
layouts/default.twig
pages/index.twig
pages/about.twig
pages/blog/index.twig
pages/blog/post.twig
pages/readme.twig
partials/nav.twig
partials/footer.twig
partials/post-card.twig
public/assets/
style.css ← edit me

Features:

  • Homepage shows latest 5 posts from a blog collection
  • Blog index lists all posts
  • Reusable post card partial
  • Serif typography for readability

Note: The blog starter expects a blog collection with the blog schema to exist. Create one in the admin to see posts rendered in the templates. The templates gracefully handle the case where no blog collection exists yet.

Best for: Personal blogs, content-focused sites, writing platforms.


A portfolio site for showcasing projects with a visual grid layout.

Pages: Home, Work, About, Contact

Files created:

tcms-data/builder/
layouts/default.twig
pages/index.twig
pages/work.twig
pages/about.twig
pages/contact.twig
pages/readme.twig
partials/nav.twig
partials/footer.twig
public/assets/
style.css ← edit me

Features:

  • Featured work grid on homepage
  • Full project gallery on work page
  • Skills tags on about page
  • Contact form
  • Subtle hover animations on project cards

Best for: Designers, developers, agencies, creatives.

A complete HTML5 document with:

  • <meta charset> and <meta viewport>
  • {% block title %} defaulting to cms.config('domain')
  • {% block description %} for SEO meta
  • {% block head %} for additional head content
  • {% block content %} for page body
  • Nav and footer partials included automatically

Dynamic navigation using the builder nav function:

{% set pages = cms.builder.nav() %}
{% for p in pages %}
<a href="{{ p.route }}">{{ p.title }}</a>
{% endfor %}

cms.builder.nav() returns top-level pages that are published (not draft) and have navigation enabled (nav: true), in the order defined by the order file (.order.json). Your nav updates automatically when you add, remove, or reorder pages in the admin.

See Navigation for subnav() and navTree() functions.

A simple footer with dynamic copyright year via {{ 'now' | date('Y') }} and the domain name.

Each starter ships a real CSS file at public/assets/style.css rather than dumping styles inline in the layout. The layout references it with the cms.builder.css() Twig helper:

{{ cms.builder.css('style.css') }}
{# → <link rel="stylesheet" href="/assets/style.css?v=1714607400"> #}

The helper resolves the path against your configured assets directory and appends an mtime cache-buster automatically — so when you edit the file, browsers pick up the new version on next load without manual versioning.

This setup is intentional: it works immediately without any build step and shows you exactly the pattern you’d use for any other CSS, JS, font, or image asset. When you outgrow plain CSS, swap it for one of:

  • Sass/SCSS compiled by your build tool
  • Vite (run tcms builder:frontend to scaffold it)
  • Tailwind CSS
  • Any other pipeline that emits CSS files

T3 does not own your CSS build pipeline — it just helps you reference whatever ends up in public/assets/.

Every starter ships a jumpstart.json alongside its manifest.json. It is the single source of truth for everything the scaffold installs into your data store: page records, supporting schemas, supporting collections, and any sample objects.

StarterWhat jumpstart.json installs
minimal2 pages (Home + Getting Started)
portfolio5 pages (Home, Work, About, Contact, Getting Started)
blog5 pages + the reserved blog collection + 5 sample posts (featured + categories + tags populated)
business5 pages + a service schema + a services collection + 4 sample services (Strategy, Design, Development, Ongoing Support)

The import runs automatically as part of tcms builder:init. If it fails for any reason — schema conflict, disk error, etc. — the scaffold itself still succeeds (templates have already been copied) and you can re-run manually:

Terminal window
tcms jumpstart:import resources/builder/starters/blog/jumpstart.json

Every starter ships with inline <style> tags so it works without any build step. When you’re ready for a proper asset pipeline, add it with one flag during init:

Terminal window
tcms builder:init business --frontend

Or after the fact (idempotent):

Terminal window
tcms builder:frontend

Both install the same Vite scaffold to <projectRoot>/frontend/. See builder:frontend for the full reference.

After running builder:init, you own all the template files. Common next steps:

  1. Edit the stylesheet — open public/assets/style.css and tweak as needed. The layout already loads it via {{ cms.builder.css('style.css') }}.
  2. Edit page templates — replace placeholder content with cms.* calls to your collections
  3. Add more pages — create new page objects in the admin under Site Builder
  4. Reorder pages — use the admin’s drag-drop reorder mode to set the navigation order (see Reordering Pages)
  5. Create partials — extract repeated patterns into partials/ templates

No build or generate step is needed — the page router serves your routes from the live collection.

Starters live in resources/builder/starters/{name}/. Each starter needs:

The manifest describes the starter for the picker UI — name, description, version. That’s it:

{
"name": "My Starter",
"description": "A description of what this starter provides",
"version": "1.0.0"
}

The starter’s pages and any seed content live in jumpstart.json, in the standard JumpStart format. List the page records first, in the order you want them to appear in the navigation:

{
"name": "My Starter Data",
"description": "Pages + sample content for the starter",
"version": "1.0.0",
"objects": [
{
"collection": "builder-pages",
"id": "home",
"data": { "id": "home", "title": "Home", "route": "/", "template": "index", "draft": false, "nav": true, "data": {} }
},
{
"collection": "builder-pages",
"id": "about",
"data": { "id": "about", "title": "About", "route": "/about", "template": "about", "draft": false, "nav": true, "data": {} }
}
]
}

Each page object maps to a builder-page schema record. Required fields inside data: id, title, template. Useful optional fields: route, draft, nav. The inner data: {} is the page’s free-form JSON data field (exposed at render time as page.data.*) — pass an empty object to satisfy schema validation, or fill it with per-page hero text / CTAs / etc. The schema also supports description, image, status, redirectTo, sitemap, changeFrequency, and priority — set them per page in the jumpstart if you want them pre-populated.

Page order in the admin sidebar follows the order of objects in jumpstart.json (the page router preserves insertion order in the collection index).

To install supporting schemas, collections, or other objects (e.g. a services collection alongside the pages), use the standard JumpStart sections — schemas, collections, and additional objects for non-page records. See the business starter for a worked example.

Organize templates in the standard directory structure:

my-starter/
manifest.json
jumpstart.json
layouts/
default.twig
pages/
index.twig
about.twig
partials/
nav.twig
footer.twig

Files are copied directly to tcms-data/builder/{category}/. Page templates use {% extends 'layouts/default.twig' %} directly — there’s no layout field on pages.