Props
-
snapshot
MakeswiftComponentSnapshot
required
The Makeswift snapshot to render.
-
The label of the component used in the Visual Builder.
-
The type of the registered Makeswift component. This should match the
type
property that was used when calling
registerComponent.
Example
The following examples expects that you have integrated Makeswift into your
project according to the App Router
Installation guide. If you have not,
you may need to tweak the code snippets below to match your project setup and
file structure.
The following example registers a <Header>
component that is editable by the user and will be displayed on each page.
Creating the component
First, you’ll need a React component. Here, we’re going to create one that takes three properties: className
, logo
, and links
.
@/components/header/index.tsx
"use client";
import Image from "next/image";
import Link from "next/link";
interface Props {
className: string;
logo: {
src?: string;
alt: string;
width: number;
height: number;
};
links: Array<{
label: string;
link: { href: string };
}>;
}
export function Header({ className, links, logo }: Props) {
return (
<header className={className}>
<nav className="mx-auto max-w-6xl flex items-center justify-between gap-4 p-8">
{logo?.src && (
<div className="flex items-center justify-start self">
<Image
src={logo.src}
alt={logo.alt}
width={logo.width}
height={logo.height}
/>
</div>
)}
<ul className="flex gap-6">
{links.map((item, i) => (
<li key={i} value={i.toString()}>
<Link href={item.link.href}>{item.label}</Link>
</li>
))}
</ul>
</nav>
</header>
);
}
Registering with Makeswift
Next, this component needs to be registered with Makeswift. This example registers the same three properties: className
, logo
, and links
. Notice these property names match the property names defined in the Header
component.
In registerComponent
the hidden
property is set to true
which hides it
from being listed in the Component Tray. This is because we will be
hard-coding where this component will be incorporated into the page and we
don’t want the user to drag and drop multiple instances of it.
@/components/header/register.ts
import {
Group,
Image,
Link,
List,
Number,
Style,
TextInput,
} from "@makeswift/runtime/controls";
import { Header } from "./";
import { runtime } from "@/makeswift/runtime";
export const HEADER_COMPONENT_TYPE = "makeswift-header";
const logo = Group({
label: "Logo",
preferredLayout: Group.Layout.Popover,
props: {
src: Image({ label: "Logo" }),
alt: TextInput({ label: "Alt text", defaultValue: "Logo alt" }),
width: Number({ label: "Width", suffix: "px", defaultValue: 200 }),
height: Number({ label: "Height", suffix: "px", defaultValue: 200 }),
},
});
const links = List({
label: "Links",
type: Group({
label: "Link",
props: {
label: TextInput({ label: "Text", defaultValue: "Text" }),
link: Link({ label: "URL" }),
},
}),
getItemLabel: (item) => item?.label ?? "Text",
});
runtime.registerComponent(Header, {
type: HEADER_COMPONENT_TYPE,
label: "Site Header",
hidden: true,
props: {
className: Style(),
logo,
links,
},
});
Each time you register a component, you’ll need to import it into both your
layout.tsx
file and your makeswift/provider.tsx
file.
Rendering the component
Then, you’ll need to retrieve the snapshot of the component from the Makeswift API by calling getComponentSnapshot
with a unique ID and pass that snapshot to <MakeswiftComponent>
.
Here, we are adding the <Header>
to the root layout.tsx
file so that it shows up on each page.
import { draftMode } from "next/headers";
import { MakeswiftProvider } from "@/makeswift/provider";
import "@/makeswift/components";
import "./globals.css";
import { MakeswiftComponent } from "@makeswift/runtime/next";
import { getSiteVersion } from "@makeswift/runtime/next/server";
import { HEADER_COMPONENT_TYPE } from "@/components/header/register";
import { client } from "@/makeswift/client";
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const myHeaderSnapshot = await client.getComponentSnapshot(
`my-header-id`, //unique identifier of the component rendered on the page
{ siteVersion: await getSiteVersion() }
);
return (
<html lang="en">
<body>
<MakeswiftProvider previewMode={(await draftMode()).isEnabled}>
<MakeswiftComponent
snapshot={myHeaderSnapshot}
label={`Site Header`}
type={HEADER_COMPONENT_TYPE}
/>
{children}
</MakeswiftProvider>
</body>
</html>
);
}
The header should now be visible on each page within the Visual Builder.