Your First Component
Step 1: Scaffold the Vue component
In your Nuxt project, run the interactive generator:
npx cwa make:component
It prompts for the component name, type, and which API behaviours you need. Once complete it writes app/cwa/components/Title/Title.vue and outputs the php bin/console command to run in your API project.
Open the generated file and fill in your template:
<template>
<h1 class="text-4xl font-bold">
{{ resource?.data?.title || 'No Title' }}
</h1>
</template>
See cwa make:component for the full reference and the image/collection variants.
Step 2: Create the API entity
Run the command output by the CLI in your API project — for example:
php bin/console make:api-component Title --publishable
Then run the migration:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
See make:api-component for all available flags.
Step 3: Add the admin tab
Create app/cwa/components/Title/admin/Title.vue — the editing form shown in the inline CMS:
<template>
<CwaUiFormLabelWrapper label="Title">
<CwaUiFormInput v-model="titleModel.model.value" />
</CwaUiFormLabelWrapper>
</template>
<script setup lang="ts">
import { useCwaResourceManagerTab, useCwaResourceModel } from '#imports'
const { exposeMeta, iri } = useCwaResourceManagerTab({ name: 'Title' })
const titleModel = useCwaResourceModel<string>(iri, 'title')
defineExpose(exposeMeta)
</script>
Step 4: Register in nuxt.config
// nuxt.config.ts
export default defineNuxtConfig({
cwa: {
resources: {
Title: {
name: 'Title',
description: 'A heading or section title',
defaultData: { title: 'New Title' }
}
}
}
})
Try it
Log in as admin, open edit mode, click + in a component group, find Title, add it, and type in the tab. Changes save automatically. Click Publish to make it live.
Next Steps
- Add an image → Images & Media
- Style variants → Alternative UI Variants
- Multiple admin tabs → create additional files in
admin/, each withuseCwaResourceManagerTab({ name: '...', order: N }) - Full composable reference → useCwaComponent