Content Recipes
Copy-paste solutions for common content patterns. Each recipe shows the markdown you write and notes on key points.
For deeper explanations, see the Writing Content guide.
Note: These recipes use generic type names (Hero, Features, FAQ, etc.). Your site's template may use different names — check the existing .md files in your site to see what types are available, and your template's documentation for details.
Sections
Hero with Image and CTA Buttons
A bold landing section with headline, description, buttons, and a hero image.
---
type: Hero
theme: gradient
---
#> Welcome to
# Acme Corp
## Build something great
We help teams ship products faster with modern tools and beautiful design.
[Get Started](/signup)
[Watch Demo](/demo)
- The
#>label line creates a pretitle ("Welcome to") above the title. A smaller heading directly above the title (### → #) does the same. - Standalone links become CTA buttons. The section type decides how they look.
- The image, links, and paragraphs are ingredients — the section type arranges them.
Multi-Line Hero with Accented Text
A bold hero with a two-line headline and the second line styled differently.
---
type: Hero
theme: dark
---
#> Our Mission
# Build the future
# [with confidence]{accent}
We help teams ship products faster with modern tools and beautiful design.
[Get Started](/signup)
[Learn More](/about)- Two consecutive
#headings merge into a multi-line title — one<h1>with visual line breaks. [with confidence]{accent}highlights the second line with accent styling (color + bold).- The
#>label line creates a pretitle ("Our Mission") above the title. A smaller heading directly above the title (### → #) does the same.
Feature Grid with Icons
A grid of feature cards, each with an icon, title, and description.
---
type: Features
---
# Why Choose Us
We've built the tools you need.
### Lightning Fast

Sub-second load times across all devices.
### Bank-Grade Security

Enterprise security with end-to-end encryption.
### Easy Integration

Connect with your existing tools in minutes.
### 24/7 Support

Real humans ready to help around the clock.
### Analytics Built In

Track everything that matters, nothing that doesn't.
### Open Source

Transparent, auditable, community-driven.- Each
###heading starts a new item (card). - Icons use the
lu-nameformat (Lucide). Browse all icons visually at react-icons.github.io/react-icons.
FAQ Section
Expandable questions and answers.
---
type: FAQ
---
# Frequently Asked Questions
### How do I get started?
Sign up for a free account and follow our quickstart guide. You'll have your first project running in under five minutes.
### Is there a free plan?
Yes! Our free tier includes unlimited projects and up to 3 team members. No credit card required.
### Can I use my own domain?
Absolutely. Connect any custom domain in your project settings. We handle SSL certificates automatically.
### How do I cancel?
You can cancel anytime from your account settings. No questions asked, no hidden fees.- Each
###heading becomes a question. The paragraphs below it are the answer.
Pricing Table
Pricing tiers with feature lists.
---
type: Pricing
---
# Simple, Transparent Pricing
Choose the plan that's right for you.
### Starter
$9/month
Perfect for individuals and small projects.
- 5 projects
- 1 team member
- Community support
- Basic analytics
[Get Started](/signup?plan=starter)
### Pro
$29/month
For growing teams that need more.
- Unlimited projects
- 10 team members
- Priority support
- Advanced analytics
- Custom domains
[Get Started](/signup?plan=pro)
### Enterprise
Custom
For organizations with advanced needs.
- Everything in Pro
- Unlimited team members
- Dedicated support
- SLA guarantee
- SSO / SAML
[Contact Sales](/contact)
```yaml:pricing
billingToggle: true
annual:
starter: 7
pro: 24
enterprise: null
```- Each
###heading is a pricing tier with its own paragraphs, lists, and links. - The YAML data block passes structured data (like billing toggle config) to the section.
Testimonials
Quote cards from customers.
---
type: Testimonials
---
# What Our Customers Say
### Jane Smith
> "Absolutely transformed how we build websites. We shipped our redesign in half the time."
CEO at TechCo

### Mike Johnson
> "The best developer experience I've found. My team loves working with it."
CTO at StartupX

### Sarah Chen
> "Finally, a tool where our content team and engineering team don't step on each other."
VP Engineering at ScaleUp
- Each
###is a person. Their quote uses blockquote syntax (>). - The paragraph after the quote is their role/company.
- Images become avatars. The order of quote, role, and image within each item doesn't matter.
Team Page
Photo + name + role cards.
---
type: Team
---
# Our Team
The people behind the product.
### Sarah Chen

Lead Engineer
Building systems that scale. Previously at Google and Stripe.
[LinkedIn](https://linkedin.com/in/sarah){target=_blank}
### Alex Rivera

Head of Design
Crafting experiences users love. Award-winning designer.
[Portfolio](https://alex.design){target=_blank}
### Jordan Park

Product Manager
Turning ideas into shipped features. 10 years in SaaS.
[Twitter](https://twitter.com/jordan){target=_blank}- Each
###is a team member. Provide their image, role, bio, and links — the section type arranges them.
Image Gallery
A set of images displayed in a grid.
---
type: Gallery
---
# Project Gallery





- Just list your images. The section type handles the gallery layout.
- Alt text is important for accessibility and may be used as captions.
Logo Cloud
A row of partner or client logos.
---
type: LogoCloud
---
# Trusted By




- Just list your logo images. Use SVG for best quality at any size.
Contact Form
A form section using structured data for field configuration.
---
type: Contact
---
# Get in Touch
We'd love to hear from you. Fill out the form below and we'll get back to you within 24 hours.

```yaml:form
fields:
- name: name
label: Full Name
type: text
required: true
- name: email
label: Email Address
type: email
required: true
- name: subject
label: Subject
type: select
options:
- General Inquiry
- Technical Support
- Partnership
- name: message
label: Message
type: textarea
required: true
submitLabel: Send Message
successMessage: Thanks! We'll be in touch soon.
```- The YAML data block configures the form. The tag name (
form) and field structure depend on what your template's Contact type expects — check your template's documentation.
Navigation & Layout
Header with Navigation
Site-wide header. This lives in layout/header.md.
---
type: Header
---
{role=icon}
[Home](/)
[Products](/products)
[Docs](/docs)
[Pricing](/pricing)
[Contact](/contact)- A file in
layout/makes this appear on every page. - The icon with
role=iconbecomes the site logo. - Standalone links become navigation items.
Auto-navigation alternative: Some Header types automatically build navigation from your page structure, so you may not need to list links manually. Check the header file that came with your template.
Footer with Link Columns
Site-wide footer. This lives in layout/footer.md.
---
type: Footer
---
### Product
[Features](/features)
[Pricing](/pricing)
[Changelog](/changelog)
[Roadmap](/roadmap)
### Company
[About](/about)
[Careers](/careers)
[Blog](/blog)
[Press](/press)
### Legal
[Privacy Policy](/privacy)
[Terms of Service](/terms)
---
{href="https://twitter.com/example" target=_blank}
{href="https://github.com/example" target=_blank}
{href="https://linkedin.com/company/example" target=_blank}
© 2025 Acme Corp. All rights reserved.- Each
###heading creates a link column. - Clickable icons (with
href) become social media links. - The final paragraph is the copyright notice.
Pages & Routes
Adding a New Page
Create a folder under pages/ and add a .md file:
pages/
├── home/
├── about/
└── pricing/ ← new page
└── content.md---
type: Pricing
---
# Our Plans
Choose the right plan for you.The page automatically appears at /pricing and shows up in navigation. The title defaults to the folder name.
To set a custom title, description, or ordering, add a page.yml:
title: Pricing
description: Our plans and pricing
order: 3Tip: Use index: in site.yml (not pages:) to set your homepage. This way new pages are auto-discovered in navigation without manually updating a list.
Linking Between Pages
Use the page: protocol for internal links that won't break if you reorganize:
[See our pricing](page:pricing)
[Read the docs](page:docs)
[Contact us](page:about#contact)For simple cases, plain paths work too:
[Pricing](/pricing)But page: links survive if you move pages to different folders. For pages you link to often, add an id in their page.yml:
# pages/docs/getting-started/installation/page.yml
id: installation
title: Installation GuideNow [Install guide](page:installation) works no matter where the page lives.
Blog with an Article List and a Page per Article
Set up a blog: a list of articles, a page for each one, and a few more articles at the bottom of each.
1. Declare a query in site.yml (or in queries.yml):
queries:
articles:
schema: '@/article'
sort: date desc2. Add article files in records/article/ — every file there is a record:
records/article/
├── hello-world.md
├── new-feature.md
└── tips-and-tricks.mdEach article has frontmatter:
---
title: Hello World
date: 2025-01-15
description: Our first blog post
---
Welcome to our blog! Here's what we've been building...3. Create the blog page, which names the query:
pages/blog/
├── page.yml
└── list.md# pages/blog/page.yml
title: Blog
query: articles<!-- pages/blog/list.md -->
---
type: ArticleList
---
# Blog
The latest from our team.4. Give each article a page, with a [slug] folder inside the blog:
pages/blog/
├── page.yml
├── list.md
└── [slug]/
├── article.md
└── more.md<!-- pages/blog/[slug]/article.md -->
---
type: Article
---<!-- pages/blog/[slug]/more.md -->
---
type: ArticleList
fetch:
query: articles
current: exclude # every article except the one this page shows
limit: 3
---
# More from the blog- The
[slug]folder is a parametric page: one page per article (/blog/hello-world). It takes the blog page'squery: articles, and itsArticlesection shows the article the URL names. - The
more.mdsection names the same query, leaves out this page's article, and keeps three. - These pages don't appear in navigation — they're reached from the list, and from every list of the query: each article carries
$route, the URL of its page, which list components use for the card's link. See Linking to a record. - To show the latest three on the home page, add a section there with
fetch: { query: articles, limit: 3 }.
Adding Search to Your Site
1. Enable search in site.yml:
services:
search:
enabled: true2. Check your template — most templates include search UI that works automatically once search is enabled.
That's it. The build generates a search index, and the search UI loads it on demand.
Optional configuration:
services:
search:
enabled: true
exclude:
routes:
- /admin
- /draftSee the Search guide for full configuration options.
Content Patterns
Hero with Background Image
Any section can have a background image — just add background: to the frontmatter. The simplest form is a URL:
---
type: Hero
theme: dark
background: /images/hero-bg.jpg
---
# Transform Your Business
Start building with modern tools today.
[Get Started](/signup)For busy images, add an overlay to keep text readable:
---
type: Hero
theme: dark
background:
image:
src: /images/hero-bg.jpg
position: center
overlay:
enabled: true
type: dark
opacity: 0.6
---
# Transform Your Business
Start building with modern tools today.
[Get Started](/signup)- Background images appear behind the content, covering the full section.
- Overlays add a semi-transparent layer so text stays readable. Use
type: darkortype: light. - Adjust
opacity(0 to 1) — higher values make the overlay stronger.
Section with Background Color
Any section can use a solid color as its background:
---
type: CTA
theme: dark
background: "#1e1e2e"
---
# Ready to Get Started?
Join thousands of teams already using our platform.
[Sign Up Free](/signup)- You can use hex colors (
#1e1e2e), CSS color names (navy), or theme variables (var(--primary-900)). - When using a dark background color, set
theme: darkso the text colors adapt.
Section with Gradient Background
---
type: Hero
theme: dark
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%)
---
# Build Something Beautiful
Modern tools for modern teams.
[Get Started](/signup)- Any CSS gradient works:
linear-gradient(...),radial-gradient(...),conic-gradient(...). - Combine with
theme: darkfor light text on dark gradients.
Hero with Background Video
---
type: Hero
theme: dark
background:
video:
src: /videos/hero.mp4
poster: /images/hero-poster.jpg
overlay:
enabled: true
type: dark
opacity: 0.5
---
# See It in Action
Watch how easy it is to get started.
[Try Free](/signup)- Video backgrounds automatically show a still image for users who prefer reduced motion.
- The poster image shows while the video loads.
- You can also use the simple form:
background: /videos/hero.mp4(video detected by extension).
Multi-Section Page
A complete page with several sections, each using a different type:
pages/home/
├── page.yml
├── 1-hero.md
├── 2-logos.md
├── 3-features.md
├── 4-testimonials.md
├── 5-pricing.md
└── 6-cta.mdEach file has its own type: in the frontmatter. The number prefix controls the order. You can freely add, remove, or reorder sections by changing the filenames.
Quick Reference
Content cheat sheet
| What you write | What it becomes |
|---|---|
# Heading (first) | Main title |
## Heading (after title) | Subtitle |
#> Heading (a label line) | Pretitle / eyebrow text |
| Paragraphs | Body text |
[text](url) on its own line | Button / CTA |
 | Image |
 | Icon |
> quote | Blockquote |
- item | List |
### After content | New item (card, entry) |
```yaml:tag | Structured data |
Icon family codes
Browse all icons visually at react-icons.github.io/react-icons.
| Code | Library |
|---|---|
lu | Lucide |
hi / hi2 | Heroicons v1 / v2 |
fi | Feather |
pi | Phosphor |
tb | Tabler |
bs | Bootstrap Icons |
md | Material Design |
ai | Ant Design Icons |
ri | Remix Icon |
si | Simple Icons |
io5 | Ionicons 5 |
bi | Boxicons |
vsc | VS Code Codicons |
wi | Weather Icons |
gi | Game Icons |
fa / fa6 | Font Awesome 5 / 6 |
Analytics & Third-Party Scripts
To add Google Analytics, tracking pixels, or any other service that asks you to "paste this code into your site's <head>":
- Create a file called
head.htmlin your site folder (next tosite.yml) - Paste the code the service gives you
That's it. The build injects it into every page automatically.
⚠️ This works where your site's pages are built from your files —
uniweb export, oruniweb deploy --host=<adapter>. If you publish to Uniweb Cloud (uniweb publish), the host builds your pages from your synced content andhead.htmlis not applied — your file is kept and synced, but a script in it will not run there.
⭐ For a tracking script, there is a shorter way that works everywhere
If the service gave you a single <script src="…"> line and nothing else — most analytics tools and tag managers do — you can skip head.html and name the URL instead:
# site.yml
services:
tracking:
scripts:
- https://www.example-analytics.com/tag.js?id=YOUR-IDSame script, same service, same data. The difference is who loads it: the site's runtime does, so it works on every host — including Uniweb Cloud, where head.html does not apply.
It also gets you two things a pasted snippet does not: it is loaded once per page even as visitors move around your site, and if you add consent: required the script is never fetched at all until a visitor agrees, rather than loaded and then asked to behave.
Use head.html instead when the service's snippet has more than a <script src> in it — some add a few inline configuration lines, and those have nowhere to go in a URL. See Tracking for the full reference.
Google Analytics
<!-- site/head.html -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>Replace G-XXXXXXXXXX with your Measurement ID (found in Google Analytics → Admin → Data Streams).
Multiple scripts
You can put as many scripts as you need in head.html. Just paste them one after another:
<!-- Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>/* ... */</script>
<!-- Cookie consent -->
<script src="https://cdn.example.com/consent.js"></script>See Also
- Writing Content — Full guide to writing content
- Layout Areas — Header, footer, and sidebar details
- Linking — Stable
page:links - Records — How records work, the
records/folder and itsfolder.yml, and a page per record - Search — Search configuration