Reputation: 63
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
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