Skip to content

Latest commit

 

History

History
104 lines (73 loc) · 7.94 KB

File metadata and controls

104 lines (73 loc) · 7.94 KB

This is an EmDash site -- a CMS built on Astro with a full admin UI.

Commands

npx emdash dev        # Start dev server (runs migrations, seeds, generates types)
npx emdash types      # Regenerate TypeScript types from schema

The admin UI is at http://localhost:4321/_emdash/admin.

Key Files

File Purpose
astro.config.mjs Astro config with emdash() integration, database, and storage
src/live.config.ts EmDash loader registration (boilerplate -- don't modify)
seed/seed.json Schema definition + demo content (collections, fields, taxonomies, menus, widgets)
emdash-env.d.ts Generated types for collections (auto-regenerated on dev server start)
src/layouts/Base.astro Base layout with EmDash wiring (menus, search, page contributions)
src/pages/ Astro pages -- all server-rendered

Skills

Agent skills are in .agents/skills/. Load them when working on specific tasks:

  • building-emdash-site -- Querying content, rendering Portable Text, schema design, seed files, site features (menus, widgets, search, SEO, comments, bylines). Start here.
  • creating-plugins -- Building EmDash plugins with hooks, storage, admin UI, API routes, and Portable Text block types.
  • emdash-cli -- CLI commands for content management, seeding, type generation, and visual editing flow.

Documentation

The EmDash docs are available as an MCP server at https://docs.emdashcms.com/mcp. When you need to verify an API, hook, config option, field type, or pattern, call search_docs against the live documentation rather than relying on training-data recall. The docs reflect current behaviour; assumptions may not.

This template ships with .mcp.json, .cursor/mcp.json, and .vscode/mcp.json so Claude Code, Cursor, and VS Code auto-discover the docs server. Other tools (OpenCode, Windsurf, etc.) need a manual one-time setup -- see docs.emdashcms.com/docs-mcp.

Rules

  • All content pages must be server-rendered (output: "server"). No getStaticPaths() for CMS content.
  • Image fields are objects ({ src, alt }), not strings. Use <Image image={...} /> from "emdash/ui".
  • entry.id is the slug (for URLs). entry.data.id is the database ULID (for API calls like getEntryTerms).
  • Always call Astro.cache.set(cacheHint) on pages that query content.
  • Taxonomy names in queries must match the seed's "name" field exactly (e.g., "category" not "categories").

This Template

A blog with posts, pages, categories, tags, full-text search, and RSS. Designed for personal writing, technical writing, indie newsletters, and anything where the writing is the product. Editorial-tech aesthetic: confident sans-serif, restrained accent, real article structure with bylines and reading time.

Pages

Page Path What it shows
Home / Featured post hero (large image + excerpt), latest posts grid
All posts /posts Article count, full post list with excerpts and tag chips
Post detail /posts/[slug] Featured image, title, body, left meta column (authors + date), right TOC + search + categories gutter
Search /search Full-text search UI
Page /pages/[slug] Static page content (Portable Text)
Category /category/[slug] Posts filtered by category
Tag /tag/[slug] Posts filtered by tag
RSS /rss.xml Generated feed

Schema

  • posts collection: title, featured_image, content (Portable Text), excerpt (text).
  • pages collection: title, content (Portable Text). Used for /about etc.
  • Taxonomies: category, tag.
  • Single primary menu (Home, About, Posts by default).

Site settings have title and tagline -- both render in the header / footer.

Visual character

Single typeface: Inter on --font-sans, used for everything including headings (with tighter letter-spacing on h1/h2). JetBrains Mono on --font-mono for inline code and code blocks. Body and headings share the same family; weight and size carry the hierarchy.

The accent is #0066cc -- used for links, the post-card title hover, and the search input focus ring. There's also a secondary text colour (--color-text-secondary) and a --color-muted for meta info. Don't add a second accent.

The article layout is the standout feature: a three-column reading view with a left meta column (author bylines, date), centred 680px body column, and a right gutter for search, table of contents, and categories. Don't flatten that into one column on desktop -- the layout signals "this is something to read".

Customisation

src/styles/theme.css is the only file to edit for visual changes. Every CSS variable from Base.astro is listed there as a commented default -- uncomment and change to override. The dark mode palette is defined inside Base.astro itself; light-mode overrides in theme.css won't affect dark mode. To customise dark mode, add @media (prefers-color-scheme: dark) and :root.dark rules in theme.css.

Fonts are configured in astro.config.mjs under fonts:. To swap the body face, change the name: for the entry bound to cssVariable: "--font-sans". Good alternatives: Geist, IBM Plex Sans, Söhne (if you have a licence), Public Sans. If you want a serif-bodied blog, swap to a humanist serif like Source Serif, Crimson Pro, or Lora -- but then also raise --font-size-base to 1.0625rem for readability.

CSS variables worth knowing:

  • --color-accent, --color-accent-hover, --color-on-accent, --color-accent-ring
  • --color-bg, --color-bg-subtle, --color-surface, --color-text, --color-text-secondary, --color-muted, --color-border, --color-border-subtle
  • --font-sans, --font-mono
  • --tracking-tight / --tracking-snug / --tracking-wide / --tracking-wider -- letter-spacing tokens used across headings and meta labels
  • --content-width (680px) -- article body column
  • --wide-width (1200px) -- max container
  • --gutter-width (200px) -- right sidebar (TOC) on article pages
  • --meta-col-width (180px) -- left meta column on article pages
  • --avatar-size-{xs,sm,md,lg} -- byline avatar sizes at different scales

What not to do

  • Don't add a second accent colour or coloured section backgrounds. The page should be black, white, and one blue.
  • Don't replace Inter with a display sans (Bebas, Anton, etc.). Headings rely on weight contrast, not novelty faces.
  • Don't collapse the article gutter on desktop -- it's part of the reading experience.
  • Don't use stock blog copy ("Welcome to my blog", "Stay tuned for more"). Write a real tagline that says what this blog is about.
  • Don't seed the home page with three identical placeholder posts. If you only have one real post, show one real post.
  • Don't enable comments without a plan to moderate them. The template doesn't ship a comments system by default for a reason.