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>
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 →