Getting Started Guide
Everything you need to add SnipCMS to your static HTML site — from first script tag to blog posts.
1Create an account
Sign up at app.snipcms.com and create a new site. Give it a name and optionally set the domain (used for the "Edit on site" button).
You'll get a Site ID — a short string like xK9mP2nQ4rLt. You'll need this for the snippet.
2Add the snippet
Paste this before </body> on any HTML page you want to make editable:
<script src="https://app.snipcms.com/snippet.js"
data-site="YOUR_SITE_ID"></script>
That's it. One script tag. No npm, no build step, no config files. Works on any static host.
3Tag your content
Add a cms attribute to any element you want to be editable:
<h1 cms="hero-title">Welcome to my site</h1>
<p cms="hero-body">We build amazing things.</p>
<img cms="hero-image" src="photo.jpg" />
Field names can be anything — hero-title, about-paragraph, team-photo. Use descriptive names so your clients know what they're editing.
Design-safe. Clients can only edit the fields you tag. They can't add sections, move elements, or break your layout. Your HTML structure stays exactly as you built it.
Editing content
There are two ways to edit content:
From the dashboard
Go to app.snipcms.com, open your site, and click on any field in the Fields tab to edit it.
Inline on the site
Click "Edit on site" in the dashboard, or visit your page with edit mode parameters:
https://yoursite.com?cms=edit&cms_token=YOUR_JWT_TOKEN
Every tagged element gets a blue dashed outline. Click any field to open the popover editor. Type your changes, hit save — it's live instantly.
On mobile, the editor slides up as a bottom sheet. Fully touch-friendly, works on iOS Safari.
Text & HTML
For headings, paragraphs, and rich text, the snippet uses a popover editor with a formatting toolbar:
- Bold, Italic, Underline
- Bullet lists
- Links (Ctrl/Cmd + K)
- Clear formatting
Content is saved as sanitised HTML. Script tags, event handlers, and javascript: URLs are stripped automatically.
Images
Tag an <img> element with a cms attribute:
<img cms="team-photo" src="team.jpg" />
When editing, the popover shows a drag-and-drop image uploader. Supports JPG, PNG, WebP, and GIF up to 5MB.
Starter or Pro plan required. Image uploads are not available on the free tier.
Links
Tag an <a> element to make its text and URL editable. The value is stored as text||url:
<a cms="cta-link" href="#">Learn more</a>
Collections
Collections turn any repeating block on your page — an accordion of treatments, a grid of team members, a list of FAQs — into something your clients can add to, duplicate, reorder, and delete inline. No developer needed when they want a new row.
Unlike regular cms fields where every editable spot has its own unique name, a collection has one name for the whole list. Items inside it are anonymous — their fields are labeled by role (title, price, body, image) rather than by unique storage keys.
Setting up a collection
Pick the wrapper element that contains your repeating items. Add three attributes:
cms="field-name"— the storage key for the whole collection (one field total).cms-type="collection"— tells SnipCMS to treat this as a repeatable block.cms-item="selector"— a CSS selector identifying one item, e.g..accordion-itemor.team-card.cms-item-label="singular"(optional) — used in the "+ Add thing" button and field labels. Defaults toitem.
Then, inside each item, mark the editable children with cms-field="role" instead of cms=:
<div class="accordion"
cms="skindex-treatments"
cms-type="collection"
cms-item=".accordion-item"
cms-item-label="treatment">
<div class="accordion-item">
<h3 cms-field="title">Cheeks</h3>
<p cms-field="price">From £375</p>
<div cms-field="content">
<p>About this treatment...</p>
</div>
</div>
<div class="accordion-item">
<h3 cms-field="title">Chin / Jawline</h3>
<p cms-field="price">From £375</p>
<div cms-field="content"></div>
</div>
</div>
You must ship at least one item in the HTML — it serves as the template for new items the client adds. The first item's structure is cloned whenever someone clicks + Add treatment.
What your clients see in edit mode
When the page is loaded with ?cms=edit&cms_token=...:
- The wrapper gets a purple dashed outline and a collection label.
- Each item has a floating toolbar: ↑ ↓ to reorder, ⎘ to duplicate, 🗑 to delete.
- Each
cms-fieldinside an item gets the normal blue dashed outline. Clicking it opens the inline popover editor — same workflow as regular fields. - Below the wrapper, a + Add treatment button appends a fresh item (cloned from the first one, with placeholder text).
- The status bar at the bottom shows Save changes and Discard buttons as soon as anything changes.
Batch save. Field edits and structural changes (add, duplicate, delete, reorder) don't save one-at-a-time — they accumulate as unsaved changes until the client clicks Save changes in the status bar. One click, one save. Discard reverts everything back to the last saved state.
Using collections with Bootstrap accordions
Bootstrap accordions use unique id attributes with matching data-bs-target, aria-controls, and aria-labelledby references. When an item is duplicated, SnipCMS automatically rewrites these id references on the clone so each row still opens and closes independently. You don't need to do anything special — it just works.
The same id rewriting applies to any in-page anchor hrefs (href="#section") and for/id pairs on labels and inputs inside an item.
Things to know
- One field, one save. A collection counts as one field against your plan's field limit, no matter how many items it contains.
- Items are HTML. Each item is just a piece of your template — keep your own classes, styles, and markup exactly as you wrote them.
- Can't delete the last one. A collection always keeps at least one item (it's the template for new ones).
- Nested collections aren't supported — don't put a
cms-type="collection"inside another one in v1. - Images inside items work the same way as regular image fields — tag an
<img>withcms-field="photo"and the popover editor handles the upload.
Team members
On Starter and Pro plans, you can invite team members to edit your sites:
- Go to your site in the dashboard
- Open the Members tab
- Enter their email and click Send invite
They'll get an email with a link to accept the invitation. Once accepted, they can edit content on that site — but can't change settings, delete the site, or manage other members.
| Plan | Team members |
|---|---|
| Free | Owner only |
| Starter | Up to 3 |
| Pro | Unlimited |
Revision history
Every content save is recorded as a revision. You can view and restore previous versions from the dashboard:
- Open a site and go to the Fields tab
- Click the clock icon on any field
- Browse previous versions and click Restore to revert
| Plan | Revision history |
|---|---|
| Free | None |
| Starter | 30 days |
| Pro | Unlimited |
Blog: Overview
SnipCMS includes a built-in blog engine for static sites. Your clients can create, edit, and publish blog posts — all from the dashboard or inline on the site.
It works with a single HTML file. You define two templates (one for the post listing, one for a full post). SnipCMS fetches posts from the API and renders them client-side.
blog.html→ shows all published postsblog.html?post=my-slug→ shows a single post
You control all the HTML and CSS. SnipCMS only fills in the data.
Starter or Pro plan required. Blog posts are not available on the free tier. View pricing →
Blog: Setting up blog.html
Create a blog.html file on your site with this structure:
<div cms-blog>
<!-- Post card (rendered for each post on the listing) -->
<template cms-blog-list>
<article class="post-card">
<img cms-post="featured_image" />
<h2><a cms-post="link"><span cms-post="title"></span></a></h2>
<time cms-post="date"></time>
<p cms-post="excerpt"></p>
</article>
</template>
<!-- Full post (shown when ?post=slug is in the URL) -->
<template cms-blog-post>
<article class="post-full">
<a cms-post="back">← Back to posts</a>
<h1 cms-post="title"></h1>
<time cms-post="date"></time>
<img cms-post="featured_image" />
<div cms-post="body"></div>
</article>
</template>
<!-- Search & filter (optional) -->
<div cms-blog-search></div>
<div cms-blog-tags></div>
<!-- Optional states -->
<div cms-blog-loading>Loading...</div>
<div cms-blog-empty>No posts yet.</div>
<div cms-blog-pagination></div>
</div>
<script src="https://app.snipcms.com/snippet.js"
data-site="YOUR_SITE_ID"></script>
Deploy this file alongside your other pages. The snippet handles fetching, rendering, pagination, and URL routing automatically.
Style .post-card, .post-full, or whatever classes you use — SnipCMS doesn't inject any blog styles.
Blog: Template attributes
Use these cms-post attributes inside your <template> elements:
| Attribute | Element | What it does |
|---|---|---|
cms-post="title" | Any | Sets text content to the post title |
cms-post="body" | Any | Sets innerHTML to the full post body (HTML) |
cms-post="excerpt" | Any | Excerpt text (auto-generated from body if empty) |
cms-post="date" | Any / <time> | Formatted publish date. Sets datetime on <time> |
cms-post="featured_image" | <img> | Sets src. Hidden if no image set |
cms-post="link" | <a> | Sets href to blog.html?post=slug |
cms-post="back" | <a> | Sets href back to the listing page |
cms-post="slug" | Any | Sets text content to the post slug |
cms-post="tags" | Any | Renders tag links. Each tag links to ?tag=slug for filtering |
Optional container elements
| Attribute | Purpose |
|---|---|
cms-blog-loading | Shown while posts are being fetched |
cms-blog-empty | Shown when there are no published posts or post not found |
cms-blog-pagination | Auto-filled with Newer/Older links for multiple pages |
cms-blog-tags | Renders clickable tag filter buttons. Shows "All" + each tag with post count |
cms-blog-search | Renders a search input. Filters posts by title and body content |
Blog: Tags & categories
You can add tags to any blog post to categorise content. Tags are managed per site and shared across all posts.
Adding tags to posts
From the dashboard: When editing a post, type tag names in the Tags field and press Enter. Existing tags are suggested automatically.
From the site: In the inline blog editor, enter comma-separated tags (e.g. news, updates, product).
Displaying tags on posts
Add cms-post="tags" to any element in your template. The snippet renders each tag as a clickable link that filters the listing:
<!-- Inside your post card or full post template -->
<div cms-post="tags"></div>
Each tag renders as <a href="?tag=slug" class="cms-tag">Tag Name</a>, so you can style them with CSS:
.cms-tag {
display: inline-block;
padding: 4px 12px;
background: #f0f0f0;
border-radius: 4px;
font-size: 13px;
text-decoration: none;
color: #555;
}
.cms-tag:hover { background: #e0e0e0; }
Tag filter bar
Add cms-blog-tags to a container element. The snippet auto-populates it with clickable tag buttons, including an "All" option and post counts:
<div cms-blog-tags></div>
Clicking a tag navigates to blog.html?tag=tag-slug, which filters the listing to only show posts with that tag. The active tag gets an active CSS class.
Tags are automatic. When you tag a post, the tag is created if it doesn’t exist. When no posts use a tag, it’s automatically cleaned up. No tag management UI needed.
Blog: Search & filtering
Add a search input to your blog listing by including a cms-blog-search element:
<div cms-blog-search></div>
The snippet renders a search input that filters posts by title and body content. It debounces input by 500ms to avoid excessive API calls.
URL parameters
Filtering and search work via URL query parameters, which means they’re shareable and bookmarkable:
| Parameter | Example | What it does |
|---|---|---|
?tag=news | blog.html?tag=news | Shows only posts tagged "news" |
?search=launch | blog.html?search=launch | Shows posts matching "launch" in title or body |
?tag=news&search=launch | blog.html?tag=news&search=launch | Combines tag filter and search |
?page=2 | blog.html?tag=news&page=2 | Pagination preserves active filters |
All filters can be combined. Pagination links automatically carry the current tag and search parameters.
Blog: Managing posts
From the dashboard
- Open your site at app.snipcms.com
- Click the Posts tab
- Click New Post
- Fill in the title, body (HTML supported), and optionally an excerpt and featured image
- Set status to Published and save
Posts with Draft status are only visible in the dashboard — they won't appear on your site.
Inline on the site
- Visit your blog page with edit mode:
blog.html?cms=edit&cms_token=YOUR_JWT - Click + New Post above the listing
- Fill in the editor and save
- Existing posts get an Edit button you can click to modify them
Blog: SEO notes
Blog posts are rendered client-side by the snippet. A few things to be aware of:
- Google executes JavaScript and will index your posts, but it may be slower than static HTML.
- The snippet automatically updates the page
<title>and<meta description>when viewing a single post. - HTML heading tags stay intact — SnipCMS only changes the text inside them, preserving your SEO structure.
- For best results, link to your blog page from your main navigation so crawlers can discover it.
Plans & limits
| Feature | Free | Starter ($12/mo) | Pro ($49/mo) |
|---|---|---|---|
| Sites | 1 | 3 | Unlimited |
| Fields per site | 50 | Unlimited | Unlimited |
| Edits per month | 250 | Unlimited | Unlimited |
| Image uploads | No | Yes | Yes |
| Revision history | None | 30 days | Unlimited |
| Team members | Owner only | Up to 3 | Unlimited |
| Blog posts per site | Not available | 50 | Unlimited |
Hosting compatibility
SnipCMS works on any host that can serve static HTML files:
- Netlify — deploy and it just works
- Vercel — same, zero config
- Cloudflare Pages — works perfectly
- GitHub Pages — works out of the box
- Firebase Hosting — no issues
- cPanel / shared hosting — upload via FTP, done
- Any static file server — Apache, Nginx, Caddy, etc.
No server-side language required. No build step. No npm. Just HTML files with a script tag.
Ready to get started?
Start for free →