Skip to content

Author's Guide

Create and structure content with Kukui — posts, albums, playlists, and directives

Author's Guide

For: Anyone who writes or edits content for a Kukui site.

In this guide you'll: Add posts, albums, and playlists; use frontmatter, wikilinks, and transclusion; embed media with directives; and apply simple editorial and readability practices.


Common tasks

Short procedures for the things you'll do most often.

Add a post

  1. Create a new .md file in the right folder under your site's obsidian directory.
  2. Add YAML frontmatter at the top with at least title (and optionally slug, description, tags).
  3. Write your content in Markdown. Use [[Page Name]] to link to other notes.
  4. Save. If yarn watch is running, the site updates automatically; otherwise run yarn generate:nav and refresh.

Add an album

  1. Create a folder under assets/images/<album-name>/.
  2. Add album.json with name, title, description, and tags.
  3. Add photos (see naming convention in Albums and audio below).
  4. Run yarn generate:renditions and yarn generate:albums (or yarn generate).

Add a playlist (and optional podcast feed)

  1. Create a folder under assets/audio/<playlist-name>/.
  2. Add playlist.json with name, title, and description.
  3. Add audio files (e.g. .mp3, .m4a).
  4. Run yarn generate:audio (or yarn generate). The build can generate a podcast RSS feed at /feed/podcast/<playlist-name>.xml — ensure siteURL is set in your site's content.json.

Embed a video

In any markdown file, use a directive:

  • YouTube: <Youtube id="VIDEO_ID" title="Video Title" /> (ID is the 11-character part after v= in the URL.)
  • Vimeo: <Vimeo id="vimeo_id" title="Video Title" /> (numeric ID from the Vimeo URL.)

Live examples (see the output)

Everything below is rendered by Kukui from the same directive and markdown syntax you'll use. Copy and adapt these into your own notes.

YouTube

Foster City, California

Mermaid diagram

Flowcharts, sequence diagrams, and more. Here, a simple content flow:

Drop cap

Use ::dropcap or ::dropcap[inverted] to style the first letter of a paragraph. It draws the reader's eye and adds a touch of editorial polish to opening paragraphs.

SVG and images

Embed SVGs from your assets. Example: the Kukui logo.

Kukui logo

Code and tables

Syntax-highlighted code (and tables) work in any note:

// Frontmatter drives the URL
const slug = frontmatter.slug || slugify(filename);
You writeKukui gives you
[[Page]]A link to that note
<Youtube id="id" title="Title" />An embedded player
*[Transclusion target not found]*Inline transcluded section

Embed a carousel from a JSON data file (e.g. homepage hero or a custom slideshow):

Loading showcase...


Markdown and frontmatter

Content is standard Markdown (bold, italic, links, images, headers, lists, code blocks with syntax highlighting). Add frontmatter at the top of each file for metadata:

---
slug: my-page
title: My Page Title
description: A short description for listings and SEO
ogImage: /assets/og/my-page.jpg
tags: [tag1, tag2]
---
FieldPurpose
slugCustom URL path; if omitted, generated from the filename
titlePage title; defaults to filename without extension
descriptionShown in listings and as meta description
ogImageImage for social previews (path or full URL)
tagsArray of tags shown on the page

URL mapping: Folder and filename become the URL path. Spaces become hyphens; special characters are removed. Example: Bio/About Me.md with slug: about/bio/about/.


Link to other notes with Obsidian-style wikilinks:

  • [[Page Name]] — link to a note by name
  • [[Folder/Page Name]] — link to a note in another folder
  • [[Page Name|custom link text]] — link with custom label

Links resolve to the correct URL; matching is case-sensitive. If the target doesn't exist, the text is shown as plain.

Intro articles (folder, album, playlist)

You can set one note as the intro for a folder, album, or playlist. That note's body appears at the top of the page; the note is not listed as a separate article.

  • Folder intro: In the folder, add index.md or readme.md (slug index or readme). That note's content is shown on the folder page.
  • Album intro: In your articles, create a note in the Albums category whose slug matches the album name (e.g. album trip-2024Albums/trip-2024.md).
  • Playlist intro: Same idea in the Audio category — slug matches the playlist name.

Inline transclusion (embed a note)

  • *[Transclusion target not found]* — embed the full note.
  • *[Transclusion target not found]* — embed from that heading to the next same-level heading.

If the target is missing you'll see [Transclusion target not found]. Circular embeds show [Circular transclusion]. Depth is limited to 10 levels. Block refs (*[Transclusion target not found]*) are not supported.


Directives (quick reference)

Directives embed rich content with a simple ::name[...]{...} syntax.

DirectiveSyntax (one-line)Example
YouTube<Youtube id="VIDEO_ID" title="Title" /><Youtube id="dQw4w9WgXcQ" title="My Video" />
Vimeo<Vimeo id="id" title="Title" /><Vimeo id="137782295" title="My Video" />
Mermaid<Mermaid chart={...} title="Title" theme="dark" /> or fenced ```mermaid blockFlowcharts, sequence, etc.
SVG<Svg src="/path/to.svg" alt="Alt" width="..." height="..." />Inline or full-width SVG
Drop cap::dropcap or ::dropcap[inverted]Styled first letter
Photo<Photo src="..." title="Title" /> or photo="album-slug-0001"Single image from asset or album
Audio<Audio src="..." title="Title" /> or audio="playlist-001"Single track
Showcase<Showcase configData={"eyJ0aGVtZU1vZGUiOiJkYXJrIiwid2FpdEZvciI6MjUsImR1cmF0aW9uIjoxNSwiYXV0b0FkdmFuY2UiOnRydWUsImNhcm91c2VsUGFkZGluZyI6InAtMCIsImNhcm91c2VsQmFja2dyb3VuZCI6InRyYW5zcGFyZW50IiwiaXRlbXMiOlt7ImlkIjoiaW1hZ2UtMDEiLCJ0eXBlIjoiaW1hZ2UiLCJ0aXRsZSI6Ikt5byBTdWF5YW4iLCJkZXNjcmlwdGlvbiI6IkRlc2lnbiBhbmQgRGV2ZWxvcG1lbnQiLCJ1cmwiOiIvYXNzZXRzL3N2Zy9tYXN0aGVhZC0yMDI2LTAzLnN2ZyJ9LHsiaWQiOiJ5b3V0dWJlLTEiLCJ0eXBlIjoieW91dHViZSIsInRpdGxlIjoiU3ByaW5nIGluIFRva3lvIiwiZGVzY3JpcHRpb24iOiIiLCJ2aWRlb0lkIjoiZGFaeHZBa2NTbUkiLCJleHRlcm5hbExpbmsiOiJodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PWRhWnh2QWtjU21JIn0seyJpZCI6InlvdXR1YmUtMiIsInR5cGUiOiJ5b3V0dWJlIiwidGl0bGUiOiJTcHJpbmcgaW4gVG9reW8gLSBQYXJ0IDIiLCJkZXNjcmlwdGlvbiI6IiIsInZpZGVvSWQiOiJOVnZybTFaOFY1TSIsImV4dGVybmFsTGluayI6Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9TlZ2cm0xWjhWNU0ifSx7ImlkIjoidGVhc2VyLTEiLCJ0eXBlIjoidGVhc2VyIiwidGl0bGUiOiJBYm91dCBNZSIsImRlc2NyaXB0aW9uIjoiRGVtbyBvZiBhbiBhcnRpY2xlIHRlYXNlciBjb21wb25lbnQuIiwiY2F0ZWdvcnkiOiJJbmZvIiwiaW1hZ2UiOiIvYXNzZXRzL2ltYWdlcy8yMDE1LzIwMTUtMDYvMjAxNS0wNi0xMi8wMDAxLTIwMTUwNjEyLUlNR185MzYxLncxOTIwLnE3Mi5qcGciLCJleHRlcm5hbExpbmsiOiIvbm90ZXMvYmlvL2Fib3V0LyJ9XX0="} data="/assets/data/showcase-home.json" title="Title" />Carousel from a JSON data file
Audio playlist<AudioPlaylist itemsData={"[]"} playlist="name" title="Title" />Embedded playlist player
Album showcase<AlbumShowcase itemsData={"W10="} album="name" title="Title" />Album carousel

Use paths that exist in your site (e.g. under assets/). The Developer's Reference includes live examples of many of these.


File organization

Content lives under the obsidian directory. Folder structure becomes site structure:

  • Each folder can have an intro note (index.md or readme.md).
  • Filenames (and optional slug in frontmatter) determine the URL.
  • Use clear folder names; they appear in navigation and URLs (lowercased, hyphenated).

Best practices: Use H2/H3 for sections; keep one main idea per section. Code blocks use fenced syntax with a language label for highlighting.


Albums and audio

Albums

  • Location: assets/images/<album-name>/
  • Required: album.json with name, title, description, tags. Optional: waitFor, duration, masonryColumns, carouselPadding, carouselBackground, ogImage.
  • Photos: Use the naming convention NNNN-YYYYMMDD-originalname.ext (e.g. 0001-20180331-_DSC1120.jpg) for ordering. Add photos, then run yarn generate:renditions and yarn generate:albums.

Playlists and podcast feed

  • Location: assets/audio/<playlist-name>/
  • Required: playlist.json with name, title, description. Optional: image for podcast cover art.
  • Site URL: Set siteURL in your site's content.json so the podcast feed and enclosures use correct absolute URLs.
  • After adding files, run yarn generate:audio. The build can produce /feed/podcast/<playlist-name>.xml for podcast directories.

Editorial and readability

Kukui is designed for content-first, calm reading:

  • Reading measure: Body text is constrained to a comfortable line length (~65–80 characters).
  • Navigation on demand: The sidebar can hide on scroll so the page has more room; you can bring it back with a control or keyboard shortcut.
  • Accessibility: Skip-to-content link, keyboard-friendly navigation, and reduced-motion support are built in.

You don't need to do anything special — just structure your content with clear headings and paragraphs.


Publishing workflow

  1. Edit or create markdown (and assets) in the obsidian folder and assets/.
  2. Add frontmatter, use wikilinks and directives as needed.
  3. Run yarn watch during development, or yarn generate when you've added albums/audio.
  4. Build with yarn build and deploy with yarn deploy (or yarn deploy-rsync). See Deployment-Guide.

You can also author in Obsidian the app; wikilinks and many conventions are compatible. An optional Notecards plugin can preview directives in Obsidian.


When things go wrong

Wikilinks not resolving? Directives not embedding? Build errors? See Troubleshooting for wikilinks, embeds, frontmatter, and build issues.


See also