Setup preview mode in REMIX

I am building the site with Remix and try to setup the preview mode

I am using the @prismicio/client v6

export const linkResolver = (doc: PrismicDocument) => {
    return '/'
}

export const loader: LoaderFunction = async ({request}) => {
    const url = new URL(request.url);
    const token = url.searchParams.get("token")
    const documentId = url.searchParams.get("documentId")

    if (!token) {
        throw new Response("No token found.", {
            status: 404
        });
    }

    if (!documentId) {
        throw new Response("No document Id found.", {
            status: 404
        });
    }

    const previewURL = await client.resolvePreviewURL({
        defaultURL: '/',
        previewToken: token,
        documentID: documentId
        linkResolver: linkResolver 
    })

    // TODO: redirect the user to preview URL
}

How does Prismic know that I am in preview mode? Which line of code does set the preview cookie?

To my understanding, if the preview cookie is set in place, the client automatically knows that it should fetch preview content. Is this correct?

If so, how can I tell the client to always fetch preview content in my local?

Update: I got the preview cookie work, however, the client doesn't fetch the draft data. Do I need to do something to update my prismic-client setup

import * as prismic from "@prismicio/client"
import {PrismicDocument} from '@prismicio/types';

export const repositoryName = "test-repo"
const endpoint = prismic.getEndpoint(repositoryName)

export const linkResolver = (doc: PrismicDocument) => {
    return '/'
}

export const client = prismic.createClient(endpoint, {
    accessToken: process.env.PRISMIC_TOKEN
})

I also see that we need to setup the /api/exit-preview.js route. When is this route hit?

Thank you Prismic team!

Hello @dinhhuy.trinh

Thanks for reaching out to us.

I don't have any experience with REMIX, but I'd try to solve this issue.

With the latest @prismicio/client v6, you don't need to use token and documentID. resolvePreviewURL Determines the URL for a previewed document during an active preview session. The result of this method should be used to redirect the user to the document's URL.

When you initiate a client, you need to enable previews from req by the enableAutoPreviewsFromReq method. It allows the client to automatically query content from a preview session if one is active in server environments. This is disabled by default on the server.

In the /api/exit-preview.js file, you set the 'Preview Mode' exit for the current user.

You can see an example of a createClient() function and how it’s used. I have shared zip files in this thread:

Let me know if you have any questions.

Thanks,
Priyanka

Would definitely love to see Remix supported officially in the docs. I'm not sure if slicemachine is supported in Remix as well but would love to see it on this page as well: https://www.slicemachine.dev/

1 Like

Thanks for joining the conversation @reywright. We'll add your request to our board.

I've got a working solution for this. I've put it together using the documentation form the react docs and based the preview cookie on how this is handled in the .NET kit.

I setup a route at /preview which is a LoaderFunction that returns a redirect

export const loader: LoaderFunction = async ({
  request,
}) => {
  const query = url.parse(request.url, true).query;

  const preview = await client.resolvePreviewURL({
    previewToken: query.token as string,
    linkResolver,
    defaultURL: "/",
    documentID: query.documentId as string,
  });

  const cookie = createCookie(previewCookie, {
    expires: new Date("2023-01-01"),
    httpOnly: true,
    sameSite: 'lax',
    secure: false,
    path: "/"
  })

  return redirect(preview, {
    headers: {
      'Set-Cookie': await cookie.serialize(query.token),
    }
  });
};

In your page routes you can use the following.

import {   createClient, } from "@prismicio/client";
import type { LoaderFunction } from "@remix-run/node";
import { json,  createCookie} from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { accessToken, client, endpoint, previewCookie } from "prismicio";


export const loader: LoaderFunction = async ({request}) => {
  const cookie = createCookie(previewCookie)
  const value = await cookie.parse(request.headers.get("Cookie"));

  const c = createClient(endpoint, {
    accessToken,
    ref: value,
    
  })

  const documents = await c.getAllByType('blog');

  return json(documents);

};

In the .NET kit the accessing of the preview cookie is automatic and give a little more work I'm sure this would be possible here. This is merely a proof of concept.

I'd love to see official support for Remix and would be happy to help make this happen.

I've not got the time to create an example at the moment but as soon as I do I'll post a repo on Github.

2 Likes