Back to Arky

Content Website

Build a blog or content site with the CMS module

This guide shows how to build a content-driven website using the Arky CMS module.

Overview

Arky CMS is built around two primitives:

  • Collections define the shape of content, similar to a database table.
  • Entries hold the actual content inside a collection, similar to rows.

Taxonomies stay separate. Use taxonomies for hierarchical classification and filters on products, services, providers, and content-adjacent records. Use collection schemas and blocks for CMS data modeling.

Content Structure

A blog can be modeled as a blog_posts collection:

const posts = await sdk.cms.collection.create({
  store_id: storeId,
  key: 'blog_posts',
  fields: [
    {
      id: 'title',
      key: 'title',
      type: 'text',
      required: true,
      properties: { localized: true }
    },
    {
      id: 'excerpt',
      key: 'excerpt',
      type: 'text',
      required: false,
      properties: { localized: true }
    },
    {
      id: 'body',
      key: 'body',
      type: 'markdown',
      required: true,
      properties: { localized: true }
    },
    {
      id: 'hero',
      key: 'hero',
      type: 'media',
      required: false,
      properties: { multiple: false }
    }
  ]
});

Then create entries in that collection:

const post = await sdk.cms.entry.create({
  store_id: storeId,
  collection_id: posts.id,
  key: 'launch-notes',
  slug: { en: 'launch-notes' },
  fields: [
    {
      field_id: 'title',
      key: 'title',
      type: 'localized_text',
      value: { en: 'Launch Notes' }
    },
    {
      field_id: 'body',
      key: 'body',
      type: 'markdown',
      value: { en: '## What changed\n\nWe shipped a cleaner CMS model.' }
    }
  ]
});

Fetching Content

List active entries for a collection:

const { items, cursor } = await sdk.cms.entry.find({
  store_id: storeId,
  collection_id: posts.id,
  status: 'active',
  sort_field: 'created_at',
  sort_direction: 'desc',
  limit: 10
});

Get one entry by ID:

const entry = await sdk.cms.entry.get({
  id: post.id
});

For unique pages such as a homepage, create a pages collection and store a single entry with a stable key:

const pages = await sdk.cms.collection.create({
  store_id: storeId,
  key: 'pages',
  fields: [
    {
      id: 'sections',
      key: 'sections',
      type: 'list',
      required: false,
      item: {
        id: 'section',
        key: 'section',
        type: 'object',
        required: false,
        fields: [
          { id: 'heading', key: 'heading', type: 'text', required: false, properties: { localized: true } },
          { id: 'body', key: 'body', type: 'markdown', required: false, properties: { localized: true } }
        ]
      }
    }
  ]
});
Tip

You do not need a special singleton type. A collection can contain one entry when the content is singular, or many entries when it is repeatable.

Entry Structure

Collections define a schema for entry blocks. Entries store blocks that are validated against that schema, while collection-level blocks can hold singleton-style content for pages or website settings.

Content-to-content links are not a CMS primitive yet. Model repeatable data as collections and entries, and use media blocks for assets.

Media Fields

Media stays its own primitive. CMS entries reference media through media fields:

await sdk.cms.entry.update({
  id: post.id,
  fields: [
    {
      field_id: 'hero',
      key: 'hero',
      type: 'media',
      value: [{ media_id: 'media_hero123' }]
    }
  ]
});

Storefront entry responses resolve media references with URL and MIME metadata when available.

Entries are indexed through the same event and search pipeline as the rest of the store. Use query for text search and field filters for exact CMS-specific filters:

const results = await sdk.cms.entry.find({
  store_id: storeId,
  collection_id: posts.id,
  query: 'launch',
  status: 'active',
  limit: 20
});

Taxonomies

Use taxonomies when the value is primarily classification:

  • Product categories
  • Service categories
  • Provider specialties
  • Region or location groupings
  • Filter facets that should remain outside CMS schemas

Use collections and entries when the value is content data:

  • Authors
  • Testimonials
  • Case studies
  • Page sections