Skip to content

Under developmentMica is experimental and not ready for production. The API and the content format can still change, so read the release notes before you upgrade.Follow the releases.

Docs/Getting started

Start here

Getting started

Add Mica to an Astro 7 project and edit its content on your machine with the local editor.

7 min read

Mica adds an editing interface to an Astro project. The website keeps reading local files and builds to static output. This page uses the local editor, the way for a developer. Editors who are not developers need the self-hosted editor. See Choose how to run Mica if you are not sure.

Mica is experimental and not ready for production. The API and the content format can still change before 1.0. Pin the versions of the packages, and read the changelog before you upgrade.

Start from the starter

For a new site, start from the starter: an Astro site with one collection of posts, a settings page, an image with alt text, and a CI workflow that runs mica check.

npm create astro@latest -- --template micacms/mica/examples/starter
cd <your-project>
npm install
git init && git add -A && git commit -m "Start from the Mica starter"
npm run mica    # the editor, and the website's dev server for the live preview

Change the post in the editor. Mica saves it by itself, and the page beside the form shows the change at once. Publish commits the change and pushes it. Before the first Publish, create an empty repository on your Git host and push the starter's commit once:

git remote add origin <url>
git push -u origin main

Set up with a coding agent

Give your coding agent this prompt:

Read https://mica.build/setup.md and set up Mica in this project.

The agent finds out whether the project is new, an empty Astro project, or an Astro project with content collections, and installs the packages. Before it changes anything on your website, it shows you a plan in plain words: what editors will manage, and each change to your pages, with its recommendation. It continues when you agree. At the end, it checks the result with npx mica check and gives you the commands to commit. To do the setup yourself, follow the steps below.

What you need

  • Node 24 or newer
  • An Astro 7 project
  • A Git repository for the project
  • Git LFS, only when your content stores files with it. See Large files with Git LFS.

1. Install the packages

npm install @micacms/astro @micacms/core

@micacms/core defines the fields. @micacms/astro turns the model into Astro collections and writes the model for the editor. These two packages and the @micacms/editor command are the public parts of Mica. The other @micacms packages are internal: the editor and the self-hosted image install them. From 1.0, semantic versioning covers the public parts, the contract of the self-hosted image, and the content format. See the decision record Semver covers the public surface.

2. Define a content model

Create src/mica.ts. The model is plain TypeScript and imports nothing from Astro.

/**
 * The content model. Mica builds the editor's forms from it, checks every save
 * against it, and gives the pages their types. Change it here, and the build
 * writes `content/.mica/schema.json` for Mica to read: commit that file too.
 */

import { collection, date, defineSite, id, media, richText, singleton, tags, text, textarea } from "@micacms/core";

export const site = defineSite({
  root: "./content",
  collections: {
    posts: collection({
      label: "Posts",
      labelSingular: "Post",
      defaultSort: { field: "publishDate", direction: "desc" },
      fields: {
        title: text({ label: "Title", required: true, maxLength: 120, listed: true }),
        id: id({ label: "ID", from: "title" }),
        publishDate: date({ label: "Date", required: true, listed: true, width: "half" }),
        tags: tags({ label: "Tags", width: "half" }),
        cover: media({ label: "Cover image", accept: "image", alt: "required" }),
        excerpt: textarea({ label: "Teaser", rows: 3, maxLength: 300 }),
        body: richText({ label: "Text" }),
      },
    }),
  },
  singletons: {
    site: singleton({
      label: "Website",
      fields: {
        title: text({ label: "Site name", required: true }),
        description: textarea({ label: "Description", rows: 2, maxLength: 160 }),
      },
    }),
  },
});

3. Add the Astro collections

Create src/content.config.ts.

import { micaCollections } from "@micacms/astro";
import { site } from "./mica";

export const collections = micaCollections(site);

astro.config stays as it is. Run npx astro sync, or start the Astro dev server once. The loader writes content/.mica/schema.json. Commit that file: it tells Mica what your project can edit. Each build writes it again, so commit it after each model change. In CI, the build does not write the file. It fails when the committed file is not the current model.

To keep your own Astro collections beside the Mica collections, see Content model.

4. Start Mica

npx @micacms/editor start --preview

The command reads ./content, prints the address, and opens your browser on http://localhost:6422/admin/. With --preview, it also starts the project's astro dev, and stops it when the editor stops. To use a different content root, give its path: npx @micacms/editor start ./site/content. To keep the browser closed, add --no-open. Port 6422 is Mica's own, so astro dev can run at the same time. Command line lists every flag.

You should see the editor in your browser, with your collections in the menu. It opens directly. There is no sign-in, no account, no user, and no database. It listens on the local computer only, and it answers only to the names of this computer.

To pin the editor's version with the project, install it as a dev dependency and add a script:

npm install --save-dev @micacms/editor
{
  "scripts": {
    "mica": "mica start --preview",
    "check": "mica check && astro check"
  }
}

npm run mica then starts the same editor, at the version your lockfile holds, for everyone who works on the project. npm run check checks the content and the types. Without @astrojs/check in the project, use "check": "mica check".

With the editor installed, npx mica init writes a starter src/mica.ts and src/content.config.ts and never overwrites a file. npx mica check checks every entry against the model and exits with an error code when it finds a problem. Run it in CI, or after a change to the content files. Recipes has the CI steps.

While astro dev runs, the editor shows the page beside the form, with the saved changes, before Publish. Add micaPreview() to astro.config, and a click on a text in the page opens its field. See Preview changes.

5. Render the content

Use normal Astro Content Layer calls.

---
import { getCollection } from "astro:content";
import { inEditorOrder } from "@micacms/astro";
const posts = (await getCollection("posts")).sort(inEditorOrder);
---

{posts.map((post) => <h2>{post.data.title}</h2>)}

inEditorOrder sorts the entries in the order that the editor shows: the defaultSort of the collection, else the order that editors set by hand.

The model sets the type of post.data. If you rename a field, npm run check (astro check) fails at each template that uses the old name. astro build does not check types: it renders the old name as empty.

A rich-text field holds Markdoc text. renderRichText turns it into HTML. It is async. Give it the entry's data as the second argument: the images in the text then get the files of the entry, and Astro makes them smaller.

---
import { renderRichText } from "@micacms/astro";
const html = await renderRichText(post.data.body, post.data);
---

<div set:html={html} />

A singleton is a collection with one entry. getSingleton gives its data with the type of the model. It stops the build with a clear message when nobody saved the singleton yet:

import { getSingleton } from "@micacms/astro";
import { site } from "../mica";

const settings = await getSingleton(site, "site");

A relation field holds the target's ID. related and relatedAll from @micacms/astro/relations return the entries, typed, and leave out a missing one with a warning in astro dev:

---
import { related } from "@micacms/astro/relations";
const author = await related("team", post.data.author);
---

6. Save, then publish

Create an entry: fill in its title, and press Create. After that, Mica saves each change by itself. A save writes files into your checkout, and the Astro dev server reloads them at once. Run git status and git diff after a save. You should see the whole change as JSON, Markdoc and media files, uncommitted:

content/posts/we-are-hiring/
├── index.json      the fields
├── body.mdoc       the rich text, one file for each field
└── media/
    └── office.jpg

Nothing reaches the history until you press Publish. The Publish page lists every saved change and shows, field by field, what each one does. You choose which of them to publish now. Publish makes one commit of the chosen files, with your summary as the message and the trailer Published-with: Mica, and pushes it with your own Git credentials. To commit with your own tools instead, set MICA_LOCAL_PUBLISH=false.

Publish sends only Mica's own commits. If your branch has other commits that the remote does not have yet, Publish waits until you push them or move them to another branch.

When something is wrong

"There is no content model at …/.mica/schema.json". Run npx astro sync in the Astro project, or start the dev server once. Then start Mica again, and commit the file.

"Port 6422 is already in use". Another Mica is usually the cause. Stop it, or start this one on a different port: npx @micacms/editor start --port 6423.

The editor stops and names Git LFS. The content stores files with Git LFS, and Git LFS is not installed or not set up on this computer. Install it from git-lfs.com, run git lfs install once, and start Mica again.

Publish waits and names a command with git -C … switch. The content is in a Git submodule that is on a detached HEAD. Run the command, and Publish works. See Content in its own repository.

The editor shows collections that you removed, or does not show a new one. The model in content/.mica/schema.json is old. Run npx astro sync again. Mica reads the new model without a restart, and the editor tells you to load the page again.

"Somebody else saved this while you were editing". The entry changed after you opened it, for example in another browser tab. Your changes stay in the form. The editor shows both versions, and you choose Keep mine or Use theirs.

A save shows messages at fields. The entry does not agree with the model. Each message is next to its field.

A new required field makes old entries invalid. astro dev leaves those entries out and logs a warning. astro build and npx mica check fail and name them. Edit the entries, or make the field optional.

examples/company-site in the Mica repository is a complete website with a model, content, and templates. It uses large media, a map, reference data and a preview.

Next

Learn how to describe your content in Content model. When editors who are not developers must edit, go to Self-hosting. For a multilingual website, read Localization.