Tags
First go to your project settings in caisy and navigate to development -> previews and click on the "create preview" button
Secondly give your Preview any name and add a blueprint to it (we will use Page
in this example, please use the same blueprint to follow along)
After that add the Preview URL: here we need to link to the an API page we’ll be creating later, we also need to include the slug
parameter, this is the slug
field we have on the Page
blueprint, we use it to identify the part of the URL that will take us to the details of each blog article, for example /about
Further we add the project_id as a token, so we do not have to expose the the project_id as a public variable.
So the final input url for you Page preview should look like this: http://localhost:3000/{document_field.slug}?project_id={project_id}
if your app is running on port 3000.
Caisy will automatically replace the params in this url and attach another param: caisy_preview_access_token
to your preview url with your current token, when you open this preview in the ui.
Lastly you need to also turn on the Enable Live Preview
toggle
The changes for you previews save automatically
First of all, we need to install @caisy/live-preview-qwik
libraries:
yarn add @caisy/live-preview-qwik
or
npm install @caisy/live-preview-qwik
The live preview logic for caisy consists of four main parts:
Setup event connection to caisy by calling using caisyLivePreview
Wrap you graphql response with useCaisyUpdates
Highlight editable components: Adding the global css for component edit editing styles and add "data-caisy-field-name" and "data-caisy-document-id" attributes to your html elements with a helper
Connection indicator: Showcase the current connection to the live preview data stream.
Here is an example that uses the nextjs router (pages) to pull the relevant params form the current page url and initates the caisyLivePreview
const previewToken = useSignal<string | null>(null);
const xlocale = "en";
useVisibleTask$(async () => {
const w = typeof window === "undefined" ? null : window;
if (!w) return;
const urlParams = new URLSearchParams(window.location.search);
const caisy_preview_access_token = urlParams.get("caisy_preview_access_token");
previewToken.value = caisy_preview_access_token;
let close: any = null;
const start = async () => {
const token = previewToken.value;
if (!token) return;
close = livePreviewQwik.caisyLivePreview({
projectId: props.projectId,
token,
locale: xlocale,
enabled: true,
});
};
start();
return () => {
close && close();
};
});
The xlocale is just a placeholder for your current locale here.
This livePreviewQwik.caisyLivePreview function initiates the live preview, and it takes 4 properties:
projectId: this is the ID of the project we fetch the content from - you can also fetch it from the url param (project_id)
token: the preview access token coming from your account in caisy, to get this token read it form the current url.
locale(optional, default: en): since we have the functionality to add different locales to caisy, we can sync them here to fetch the correct data from the Document
enabled(optional, default: true): a boolean value to dynamically enable/disable the live-preview, in the example we use a primitive NEXT_PUBLIC_USE_DRAFT_MODE env variable, but this can be more dynamic
This useVisibleTask can run anywhere in your app. But if this has not been called yet, everything else will not work.
This is how we connect caisy with our application, it takes all the documents/components we fetch from caisy as props, it then takes care of listening to the caisy documents, and reflects the changes on the value, as a result, it returns all the same fields it takes.
In order for this to work the results need to be fetched trough graphql and every document besides it fields also needs to have the id and __typename fetched from the external api. Like you see here:
{
allPage{
edges{
node{
id
__typename
components{
... on NewsletterSignup{
id
__typename
headline
subheadline
}
... on Headline{
id
__typename
headline
subheadline
}
... on Fulltext{
id
__typename
text{
json
}
}
}
}
}
}
}
Somewhere the retuned value is used we need to wrap it once like this:
import { useCaisyUpdates } from "@caisy/live-preview-qwik";
...
const PreviewPage = component$((props: Props) => {
const { liveProps, version } = useCaisyUpdates({
Page: { ...props.Page },
Navigation: { ...props.Navigation },
Footer: { ...props.Footer },
});
return (
<Navigation {...liveProps.value?.Navigation}>
<main>
<ComponentSelector key={version.value} page={liveProps.value?.Page} />
</main>
<Footer {...liveProps.value?.Footer} />
</Navigation>
);
});
The key is used to force an re-render of all components even if the object change is deeply nested.
In order to make your fields being clickable with this edit button - we need to provide the library in the html the id of the document and the field name. Therefore we use the helper function getCaisyInspectProps
form "@caisy/live-preview-qwik"
This function is very simple:
function getCaisyInspectProps({ id, fieldName }: { id: string; fieldName: string }) {
return {
"data-caisy-document-id": id,
"data-caisy-field-name": fieldName,
};
}
and adds the necessary data attributes that the library needs to display this interface
but you need to add this everywhere, where you want the editor to be able to click the edit button.
For our example, we implement it like this in the a component:
import { getCaisyInspectProps } from "@caisy/live-preview-qwik";
...
<div className="mb-8 flex flex-col justify-start items-center gap-2.5">
{headline && (
<h1
{...getCaisyInspectProps({ id: id, fieldName: "headline" })}
className="text-4xl font-bold text-left text-slate-900"
>
{headline}
</h1>
)}
{subheadline && (
<h4
{...getCaisyInspectProps({ id: id, fieldName: "subheadline" })}
className="mt-2 text-xl text-center text-gray-400"
>
{subheadline}
</h4>
)}
</div>
in order to get the result as in seen in the screenshot.
The CaisyConnectionIndicator
component can be added in order to show the connection state.
import { CaisyConnectionIndicator } from "@caisy/live-preview-qwik";
...
return (
<>
{livePreviewEnabled && <CaisyConnectionIndicator />}
</>
)
By clicking on the Eye Icon on the top right on any Page
document will open a window with the Preview URL
we set up before
If everything went well, we should see all the UI elements we mentioned, and any change made on the caisy document will be reflected on your application!
Subscribe to our newsletters
and stay updated
While you subscribe you agree to our Privacy Policy and Terms of Service apply.
Tags