Usage with Nuxt
Before we you proceed make sure you have read the documentation for
Generating an API key
To generate an API key, see this section
For new projects
Starter kit
You can either use our Nuxt 3 - Tailwind CSS starter kit to get started or create a new project from scratch.
npx @lumenharbor/garchi-starter-kit -k nuxt
From scratch
Create new Nuxt 3 app
npx nuxi@latest init garchi-app
For existing projects
Skip the step of creating new project mentioned before and continue to the next step.
Creating components
Let's create a simple page with sections (components) Navbar, HeroContainer and Paragraph
// Navbar.vue
<template>
<header class="flex justify-between items-center p-2" v-bind="$attrs">
<img class="w-10 h-10" :src="image" />
<ul class="flex items-center space-x-2">
<NuxtLink href="/">Home</NuxtLink>
<NuxtLink href="/blog">Blog</NuxtLink>
</ul>
</header>
</template>
<script setup>
defineProps({
image: String
})
</script>
// HeroContainer.vue
<template>
<div class="h-screen w-screen grid place-items-center bg-center bg-cover"
:style="{backgroundImage: background}" v-bind="$attrs">
<div>
<h1 class="text-xl text-white bg-black/40 p-1">{{title}}</h1>
<h2 class="text-base text-white bg-black/40 p-1">{{subheading}}</h2>
</div>
</div>
</template>
<script setup>
const props = defineProps({
backgroundImage: String,
title: String,
subheading: String
})
const background = computed(() => {
return `url("${props.backgroundImage}")`
})
</script>
// Paragraph.vue
<template>
<p class="text-gray-800" v-bind="$attrs">
{{content}}
</p>
</template>
<script setup>
defineProps({
content:String
})
</script>
If you want to catch all the routes then the pages/[...slug].vue should look something like this.
<template>
<MetaTags :title="page?.title" :description="page?.description" />
<component v-for="section in page?.sections" :key="section.id" :is="components[section.name]"
v-bind="section.props"
/>
</template>
<script setup lang="ts">
const components = {
"HeroContainer": resolveComponent("MarketingHeroContainer"),
"Paragraph": resolveComponent("MarketingParagraph"),
"Navbar": resolveComponent("MarketingNavbar"),
}
const route = useRoute()
const slug = typeof route.params.slug == 'string' ? route.params.slug : route.params.slug.join('/')
const {data:page, error} = await useFetch(`https://garchi.co.uk/api/v2/page`, {
method: "POST",
body: {
"space_uid": "c7ba17eb-4004-45ef-b5b3-1d557c5c85f4c34f4a69-3d08-444f-86e0-852b",
"mode": "draft",
"slug": `/${slug}`
},
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer your_token`
}
})
useHead({
script: [
{
src: "https://garchi.co.uk/script/index.es.js",
defer: true,
}
]
})
</script>
If you notice I have added a script in the useHead. This makes the editor on the dashboard talk with your website: sections are outlined as you move over them, clicking one opens its fields, and what you type appears on the page. Without this script, the editor won't be able to talk with your website.
Note the v-bind="$attrs" on the root element of each component above. Garchi sends data-garchi-* attributes along with your content, and they need to reach that element, which is what makes a section recognisable on the page.
See the live editor guide for the whole setup.
Now this page's content could be edited from the dashboard.
⚠️ You can also add inline CSS styles. You need to add them as a prop value to the section but it won't be responsive.
You can add HTML class attribute as a prop for a section with a value of a base class and combine it with inline CSS. Sky is the limit 🚀