Skip to content

johannschopplich/cacao-kit-frontend

Repository files navigation

Cacao Kit Frontend

Cacao Kit (Frontend)

Tip

If internationalization is not a requirement for your project, you can check out the 🧱 branch without Nuxt i18n.

If this is your first time building an application with Nuxt, I recommend taking a look at the πŸ’š Kirby Nuxt Starterkit first to get a basic understanding of this tech stack. It is a Nuxt and KQL port of the Kirby starter kit.

This repository is a minimal but feature-rich Nuxt starter kit. It is the evolved version of the Kirby Nuxt Starterkit and my best practice solution to build a Nuxt based frontend on top of a headless Kirby CMS. The 🍫 Cacao Kit backend is the counterpart to this frontend.

Key Features

Note

If i18n is not a requirement for your project, you can check out the 🧱 branch without i18n.

  • 🌐 Internationalization with @nuxtjs/i18n
  • πŸ† Motto: β€œEverything is a block” – Kirby blocks define what to render for each page
  • πŸ›£οΈ All pages are rendered by the catch-all route by default (you can still create Nuxt pages)
  • 🌌 Use Kirby's page structure as the source of truth
  • πŸ«‚ Kirby Query Language with nuxt-kirby
  • πŸ› Global site data similar to Kirby's $site
  • πŸ”Ž SSR generated SEO data
  • πŸ“ Prettier & ESLint
  • πŸ”’ Pre-configured VSCode settings

A block-first approach is one of the core design decisions for this Nuxt template. This means that you can use Kirby's page structure as the source of truth, without having to replicate it in Nuxt. All pages are rendered by the catch-all route. However, you are not obliged to stick with the block-first architecture.

If you find it unsuitable or if you require custom Kirby page blueprints with custom fields, you can always create Nuxt pages and query the content using KQL. See the pages/about.vue page for an example.

Usage

Prerequisites

  1. Enable Corepack using corepack enable
  2. Install dependencies using pnpm install
  3. Adapt the relevant environment variables:
# Base URL of the Kirby backend
KIRBY_BASE_URL=
# Token for bearer authentication
# See https://github.com/johannschopplich/cacao-kit-backend#bearer-token
KIRBY_API_TOKEN=

Development

  1. Start the development server using pnpm run dev
  2. Visit localhost:3000

Production

Build the application for production with pnpm run build.

Check out the deployment documentation.

Architecture & Development

Project Structure

The Cacao Kit follows a clear architectural pattern designed around its block-first approach:

app/
β”œβ”€β”€ components/
β”‚   └── Kirby/
β”‚       β”œβ”€β”€ Block/           # Individual block components
β”‚       β”œβ”€β”€ Blocks.vue       # Block renderer
β”‚       └── Layouts.vue      # Layout renderer
β”œβ”€β”€ composables/
β”‚   β”œβ”€β”€ links.ts             # Internal link handling
β”‚   └── proxy.ts             # Development proxy utilities
β”œβ”€β”€ pages/
β”‚   β”œβ”€β”€ [...slug].vue        # Universal page renderer
β”‚   └── about.vue            # Custom page example
β”œβ”€β”€ plugins/
β”‚   └── site.ts              # Global site data management
└── queries/                 # KQL query definitions
    β”œβ”€β”€ index.ts
    β”œβ”€β”€ page.ts
    β”œβ”€β”€ site.ts
    └── prefetch.ts

Block-First Architecture

Every page is rendered through the catch-all route [...slug].vue, which dynamically renders either:

  • Layouts: Column-based content using KirbyLayouts
  • Blocks: Linear content using KirbyBlocks
<template>
  <div>
    <KirbyLayouts v-if="page?.layouts?.length" :layouts="page.layouts" />
    <KirbyBlocks v-else-if="page?.blocks" :blocks="page.blocks" />
  </div>
</template>

Adding New Blocks

  1. Create the block component in app/components/Kirby/Block/:
<!-- app/components/Kirby/Block/MyCustomBlock.vue -->
<script setup lang="ts">
import type { KirbyBlock } from '#nuxt-kirby'

defineProps<{
  block: KirbyBlock<'my-custom-block'>
}>()
</script>

<template>
  <section class="my-custom-block">
    <h2>{{ block.content.title }}</h2>
    <div v-html="block.content.text" />
  </section>
</template>
  1. Register the block in app/components/Kirby/Blocks.vue:
import { LazyKirbyBlockMyCustomBlock } from '#components'

const blockComponents: Record<string, Component> = {
  // Custom blocks
  'my-custom-block': LazyKirbyBlockMyCustomBlock,
}

Working with KQL Queries

Define reusable queries in the queries/ directory:

// app/queries/blog.ts
import type { KirbyQuerySchema } from 'kirby-types'

export const blogQuery: KirbyQuerySchema = {
  query: 'page("blog")',
  select: {
    title: true,
    children: {
      query: 'page.children.listed',
      select: {
        title: true,
        date: true,
        excerpt: 'page.text.excerpt(300)',
        cover: {
          query: 'page.cover.toFile?.resize(600)',
          select: ['url', 'alt'],
        },
      },
    },
  },
}

Use them in components:

<script setup lang="ts">
import { blogQuery } from '~/queries/blog'

const { locale } = useI18n()
const { data } = await useKql(blogQuery, {
  language: locale.value,
})
</script>

Internationalization

The kit includes full i18n support with @nuxtjs/i18n.

Custom Styling

This kit uses semantic HTML with minimal styling via new.css for demonstration. To implement your own styling, remove the import in app.vue and add your custom styles.

Deployment

Static Site Generation

For maximum performance and CDN compatibility, generate a static site:

pnpm run generate

This creates a fully static version in the dist/ directory that can be hosted on any static hosting service.

Server-Side Rendering

Deploy with full SSR capabilities:

pnpm run build

Environment Configuration

Ensure these environment variables are set in production:

# Required: Your Kirby backend URL
KIRBY_BASE_URL=https://your-kirby-backend.com

# Required: Authentication token for KQL queries
KIRBY_API_TOKEN=your-secret-token

# Optional: Public site URL for SEO and social sharing
NUXT_PUBLIC_SITE_URL=https://your-frontend.com

Preview

What's Kirby?

  • getkirby.com – Get to know the CMS.
  • Try it – Take a test ride with our online demo. Or download one of our kits to get started.
  • Documentation – Read the official guide, reference and cookbook recipes.
  • Issues – Report bugs and other problems.
  • Feedback – You have an idea for Kirby? Share it.
  • Forum – Whenever you get stuck, don't hesitate to reach out for questions and support.
  • Discord – Hang out and meet the community.
  • YouTube - Watch the latest video tutorials visually with Bastian.
  • Mastodon – Spread the word.
  • Instagram – Share your creations: #madewithkirby.

License

MIT License Β© 2023-PRESENT Johann Schopplich

About

🍫 Best practice Nuxt and KQL starter for your headless Kirby CMS

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published