Overview
Complete guide to Scalar CMS - the modern headless content management system
Introduction
Scalar CMS is a headless content management system designed for speed, clarity, and flexibility. It's built for modern development workflows, supporting static sites, dynamic apps, and everything in between.
Key features include:
- Type-safe content models with automatic validation
- GraphQL and REST APIs for flexible data access
- Real-time collaborative editing for content teams
- Multi-environment deployments and role-based permissions
Quick Example
Here's how easy it is to get started with Scalar:
import { createClient } from '@scalar/api-client';
export const scalar = createClient({
projectId: process.env.SCALAR_PROJECT_ID,
apiKey: process.env.SCALAR_API_KEY,
});
// Fetch content
export async function getBlogPosts() {
return await scalar.content.findMany({
model: 'blogPost',
include: ['author', 'categories'],
});
}
Core Components
Scalar CMS has several core parts:
Scalar Core
The data and API layer: models, validation, database handling, and schema generation. This is the foundation of your Scalar CMS setup, handling all the backend operations and data management.
Scalar Studio
A lightweight admin UI for managing content with live preview and model editing. The visual interface where content creators and editors can manage your content efficiently with real-time previews.
Scalar Models
Define fields, relationships, validation rules, and access settings. The heart of your content structure. This is where you define how your content is structured, what fields it contains, and how different content types relate to each other.
Scalar CLI
A command-line interface to scaffold content models, sync schema changes, run local servers, and deploy. Ideal for developers who prefer automation over Git-based workflows. The CLI provides powerful tools for managing your Scalar CMS setup programmatically.
Installation
Install Scalar CMS Run the installation command: ```bash npx
create-scalar@latest ```
Configure Your Setup Follow the prompts to choose your database
(PostgreSQL, SQLite, etc.), generate models, and launch the admin panel.
Launch Your CMS Once installation completes, start your development
server: bash cd your-project-name npm run dev
Your Scalar CMS admin
panel will be available at http://localhost:3000/admin
First-Time Setup
Once you've installed Scalar CMS, you'll be guided through the initial configuration process to set up your content models and database connection.
The setup wizard will walk you through: - Connecting to your chosen database - Defining your first content models - Setting up user permissions - Configuring the admin panel
Framework Integration
Scalar works seamlessly with your favorite frameworks:
import { scalar } from '@/lib/scalar';
export default async function BlogPage() {
const posts = await scalar.content.findMany({
model: 'blogPost',
orderBy: { publishedAt: 'desc' }
});
return (
<div>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
);
}
<template>
<div>
<article v-for="post in posts" :key="post.id">
<h2>{{ post.title }}</h2>
<p>{{ post.excerpt }}</p>
</article>
</div>
</template>
<script setup>
const { $scalar } = useNuxtApp();
const { data: posts } = await $scalar.content.findMany({
model: 'blogPost',
orderBy: { publishedAt: 'desc' }
});
</script>
<script>
export let data;
</script>
<div>
{#each data.posts as post}
<article>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
{/each}
</div>
import { scalar } from '$lib/scalar';
export async function load() {
const posts = await scalar.content.findMany({
model: 'blogPost',
orderBy: { publishedAt: 'desc' }
});
return { posts };
}
---
import { scalar } from '../lib/scalar';
const posts = await scalar.content.findMany({
model: 'blogPost',
orderBy: { publishedAt: 'desc' }
});
---
<div>
{posts.map(post => (
<article>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
import { useEffect, useState } from 'react';
import { scalar } from '../lib/scalar';
export function BlogList() {
const [posts, setPosts] = useState([]);
useEffect(() => {
scalar.content.findMany({
model: 'blogPost',
orderBy: { publishedAt: 'desc' }
}).then(setPosts);
}, []);
return (
<div>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
);
}
Content Models
Define your content structure with TypeScript-like syntax:
export const BlogPost = {
title: { type: 'string', required: true },
slug: { type: 'slug', from: 'title' },
excerpt: { type: 'text', maxLength: 200 },
content: { type: 'richText' },
author: { type: 'reference', to: 'Author' },
categories: { type: 'reference', to: 'Category', many: true },
publishedAt: { type: 'datetime' },
featured: { type: 'boolean', default: false },
};
Creating Content
Use the API to create and manage content programmatically:
// Create a new blog post
export async function createBlogPost(data) {
return await scalar.content.create({
model: 'blogPost',
data: {
title: data.title,
slug: data.slug,
content: data.content,
author: { connect: { id: data.authorId } },
publishedAt: new Date(),
},
});
}
// Query with filters
export async function getFeaturedPosts() {
return await scalar.content.findMany({
model: 'blogPost',
where: { featured: true },
include: ['author'],
take: 5,
});
}
GraphQL API
Access your content using GraphQL:
query GetBlogPosts($limit: Int = 10) {
blogPosts(limit: $limit, orderBy: { publishedAt: DESC }) {
id
title
slug
excerpt
publishedAt
author {
name
avatar
}
categories {
name
slug
}
}
}
Production Ready: Configure environment variables, database backups, and HTTPS before deploying.