Usage with Next Pages 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

Create new Next 13 app with pages 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>
    );
}

If you want to catch all the routes, then the pages/[[...slug]].js should look something like this.


import { useRouter } from 'next/router'
import { useEffect } from 'react'
import Navbar from '../components/Navbar'
import HeroContainer from '../components/HeroContainer'
import Paragraph from '../components/Paragraph'
import MetaTags from '../components/MetaTags'
import Script from 'next/script'

// Assume that you are getting these components from your api
const components = {
    "HeroContainer": HeroContainer,
    "Paragraph": Paragraph,
    "Navbar": Navbar,
}

export default function Page({ page }) {
    const router = useRouter()
    const { slug } = router.query

    return (
        <>
            <MetaTags title={page?.title} description={page?.description} />
            <Script src="https://garchi.co.uk/script/index.es.js" defer />
            {page?.sections?.map(section => {
                const Component = components[section.name]
                return <Component key={section.id} {...section.props} />
            })}
        </>
    )
}

// make sure to fetch data server-side
export async function getServerSideProps(context) {
    const { slug } = context.params;

    // Fetch the page data from the API based on the 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 page = await res.json()

    // return the fetched data to our React component
    return {
        props: { page },
    }
}



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 🚀