Toss
Toss

Reputation: 63

How to custom preview mode in Sanity Studio with Nextjs

I have problem to show the preview mode because the url must contain few parameter that is "category" and "slug". (example in my picture bellow).

This is the error url with undefined param

So, i cant get the param for my URL

This is my code

// structure.ts

interface Doc extends SanityDocument {
  slug: { current: any };
  categories: {
    title: string;
    description: string;
  };
}

function getPreviewUrl(doc: Doc) {
  return doc?.slug?.current
    ? `${process.env.NEXT_PUBLIC_VERCEL_URL || window.location.host}/articles/${
        doc.categories.title
      }/${doc.slug.current}`
    : `${process.env.NEXT_PUBLIC_VERCEL_URL || window.location.host}`;
}

export const defaultDocumentNode = (
  S,
  { schemaType },
) => {
  switch (schemaType) {
    case `article`:
      return 
        S.view
          .component(Iframe)
          .options({
            url: (doc: Doc) => getPreviewUrl(doc)
          })
      ]);

    default:
      return S.document().views([S.view.form()]);
  }
};

in my code above, i have implement custom component for preview mode using Iframe, and set the option to getPreviewUrl, but the doc value in this code 'url: (doc: Doc) => getPreviewUrl(doc)', just return default schema structure data that contain reference especially for the categories data. so in this case i want to get data from category schema by reference from my article schema, so i can use the data in getPreviewUrl function.

This is for the article schema

{
  "author": {
    "_ref": "31c9cd97-6fc3-45d2-a13b-d0dbfa3e4681",
    "_type": "reference"
},
"categories": [
    {
        "_key": "111749138b41",
        "_ref": "581dfb13-ab8c-4da9-8a29-1e052f6ceb76",
        "_type": "reference"
    }
],
"description": "This is the first ever article on my platform!",
"slug": {
    "_type": "slug",
    "current": "my-first-article"
},
"title": "My First Article"

}

this is my category schema structure data

category : [ { _id : string, title : string } ]

How i can get data from category schema by reference from my article schema ?, i have read the documentation on sanity.io, but still didn't get it.

Thanks for your Help!

Upvotes: 3

Views: 787

Answers (1)

Toss
Toss

Reputation: 63

I have solved my problem by change my code such the following

import Iframe from 'sanity-plugin-iframe-pane';
import { DefaultDocumentNodeResolver } from 'sanity/desk';
import { SanityDocument } from 'sanity';
import { client } from './lib/sanity.client';

interface Doc extends SanityDocument {
  slug: { current: any };
}

async function getPreviewUrl(doc: Doc) {
  const query = `*[_type == 'article' && _id == $id] {
     categories[0] -> {
       title
     }
 }`;
  const [{ categories }] = await client.fetch(query, { id: doc._id });
  return doc?.slug?.current && categories
    ? `${
        process.env.NEXT_PUBLIC_VERCEL_URL ||
        window.location.protocol + '//' + window.location.host
      }/articles/${categories?.title}/${doc.slug.current}`
    : `${process.env.NEXT_PUBLIC_VERCEL_URL || window.location.host}`;
}

export const defaultDocumentNode: DefaultDocumentNodeResolver = (
  S,
  { schemaType },
) => {
  switch (schemaType) {
    case `article`:
      return S.document().views([
        S.view.form(),
        S.view
          .component(Iframe)
          .options({
            url: (doc: Doc) => getPreviewUrl(doc),
            defaultSize: 'desktop',
            reload: { button: true },
            attributes: {},
          })

          .title('Preview'),
      ]);

    default:
      return S.document().views([S.view.form()]);
  }
};

maybe any other better solution for my case?

Upvotes: 1

Related Questions