Usage with Next App router


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 Next 14 - Tailwind CSS starter kit to get started or create a new project from scratch.

npx @adiranids/garchi-starter-kit -k next

From scratch

Create new Next app with app router

npx create-next-app@latest

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

// components/Navbar.jsx

import Link from "next/link"

export default function Navbar({ image, ...other }) {
    return (
        <header className="flex justify-between items-center p-2" {...other}>
            <img className="w-10 h-10" src={image} />
            <ul className="flex items-center space-x-2">
                <Link href="/">Home</Link>
                <Link href="/blog">Blog</Link>
            </ul>
        </header>
    );
}

</script>
// components/HeroContainer.jsx
export default function HeroContainer({ backgroundImage, title, subheading, ...other }) {
    const background = `url("${backgroundImage}")`;
    return (
        <div className="h-screen w-screen grid place-items-center bg-center bg-cover" 
        style={{backgroundImage: background}} {...other}>
            <div>
                <h1 className="text-xl text-white bg-black/40 p-1">{title}</h1>
                <h2 className="text-base text-white bg-black/40 p-1">{subheading}</h2>
            </div>
        </div>
    );
}
// components/Paragraph.jsx
export default function Paragraph({ content, ...other }) {
    return (
        <p className="text-gray-800" {...other}>{content}</p>
    );
}

Some how in app router on the date when this doc was written, it has some issue when handling home or root level route using dynamic route. So we need to create a Page.jsx component which will help us to tackle this issue.

Also we can use next/dynamic to optimise our component loading and only load those components which are utilised. You can use use the same technique for pages router.

// components/Page.jsx

import { notFound } from 'next/navigation'
import dynamic from "next/dynamic"

// if needed in other components
function GarchiDynamicComponent({ section }) {
    if(!section?.name)
        return <></>
    const DynamicComponentName = dynamic(() => import(`./${section?.name}`))
    return <DynamicComponentName subSection={section?.children} {...section?.props} />
}

export default async function Page({ slug }) {

    const res = await fetch(`https://garchi.co.uk/api/v1/page`, {
            method: 'POST',
            body: JSON.stringify({
                "space_uid": "c7ba17eb-4004-45ef-b5b3-1d557c5c85f4c34f4a69-3d08-444f-86e0-852b",
                "mode": "draft",
                "slug": `/${slug.join('/')}`
            }),
            headers: {
                "Content-Type": "application/json",
                "Authorization": `Bearer your_token`
            }
        })
    
    const pageData = await res.json()


    if (!pageData) 
        return notFound()

    return (
        <main className="max-w-8xl mx-auto">
            {pageData.sections?.map(section => <GarchiDynamicComponent key={section.id} section={section} />)}
        </main>
    )
}


Now in app/page.jsx and app/[[...slug]]/page.jsx

we can have the below code



import Page from "@/components/Page"


export default function DynamicPage({params}) {
  const slug = params.slug == "/" ? params.slug : params.slug.join("/")
  return (
        <>
            <Page slug={slug} />
            <Script src="https://garchi.co.uk/script/index.es.js" />
        </>
       
  )
}

If you notice, I have added a Script component. This makes the editor on the dashboard talk with your website so that when you click on a section in the editor on the dashboard, it will show the respective section with the prop value in the sidebar. Without this script, the editor won't be able to talk with your website.

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 🚀