import { createComponentChainLink, createPreviewAttributes, withFieldPath } from '@hygraph/preview-sdk/core';
<h1 data-hygraph-field-api-id="title" data-hygraph-entry-id={recipe.id}>
{recipe.title}
</h1>
<div
data-hygraph-field-api-id="description"
data-hygraph-entry-id={recipe.id}
data-hygraph-rich-text-format="html"
>
<div dangerouslySetInnerHTML={{ __html: recipe.description.html }} />
</div>
<div data-hygraph-field-api-id="prepTime" data-hygraph-entry-id={recipe.id}>
{recipe.prepTime}min
</div>
<div data-hygraph-field-api-id="categories">
{recipe.categories.map((category) => (
<span key={category.id}>{category.name}</span>
))}
</div>
{recipe.ingredients.map((ingredient, index) => {
const chain = [createComponentChainLink('ingredients', ingredient.id)];
const basePath = `ingredients.${index}`;
const quantityAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'quantity',
componentChain: chain,
}),
`${basePath}.quantity`
);
const unitAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'unit',
componentChain: chain,
}),
`${basePath}.unit`
);
return (
<div key={ingredient.id}>
<span>{ingredient.ingredient?.name}</span>
<span {...quantityAttributes}>{ingredient.quantity}</span>
<span {...unitAttributes}>{ingredient.unit}</span>
</div>
);
})}
{recipe.recipeSteps.map((step, index) => {
const chain = [createComponentChainLink('recipeSteps', step.id)];
const stepBasePath = `recipeSteps.${index}`;
const stepNumberAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'stepNumber',
componentChain: chain,
}),
`${stepBasePath}.stepNumber`
);
const stepTitleAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'title',
componentChain: chain,
}),
`${stepBasePath}.title`
);
const instructionAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'instruction',
componentChain: chain,
}),
`${stepBasePath}.instruction`
);
return (
<div key={step.id}>
<span {...stepNumberAttributes}>{step.stepNumber}</span>
{step.title && <h3 {...stepTitleAttributes}>{step.title}</h3>}
<div
dangerouslySetInnerHTML={{ __html: step.instruction.html }}
{...instructionAttributes}
data-hygraph-rich-text-format="html"
/>
</div>
);
})}
{step.equipment.map((equip, equipIndex) => {
const equipChain = [
createComponentChainLink('recipeSteps', step.id),
createComponentChainLink('equipment', equip.id)
];
const equipBasePath = `${stepBasePath}.equipment.${equipIndex}`;
const nameAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'name',
componentChain: equipChain,
}),
`${equipBasePath}.name`
);
const requiredAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'required',
componentChain: equipChain,
}),
`${equipBasePath}.required`
);
return (
<div key={equip.id}>
<span {...nameAttributes}>{equip.name}</span>
{equip.required && <span {...requiredAttributes}>Required</span>}
</div>
);
})}
{step.ingredientsUsed.map((ingred, ingredIndex) => {
const ingredChain = [
createComponentChainLink('recipeSteps', step.id),
createComponentChainLink('ingredientsUsed', ingred.id)
];
const ingredBasePath = `${stepBasePath}.ingredientsUsed.${ingredIndex}`;
const ingredientNameAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'ingredientName',
componentChain: ingredChain,
}),
`${ingredBasePath}.ingredientName`
);
return (
<div key={ingred.id}>
<span {...ingredientNameAttributes}>{ingred.ingredientName}</span>
</div>
);
})}
{step.tips.map((tip, tipIndex) => {
const tipChain = [
createComponentChainLink('recipeSteps', step.id),
createComponentChainLink('tips', tip.id)
];
const tipBasePath = `${stepBasePath}.tips.${tipIndex}`;
const titleAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'title',
componentChain: tipChain,
}),
`${tipBasePath}.title`
);
const contentAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'content',
componentChain: tipChain,
}),
`${tipBasePath}.content`
);
return (
<div key={tip.id}>
<h5 {...titleAttributes}>{tip.title}</h5>
<div
dangerouslySetInnerHTML={{ __html: tip.content.html }}
{...contentAttributes}
data-hygraph-rich-text-format="html"
/>
</div>
);
})}
{recipe.featuredContent && (() => {
const section = recipe.featuredContent;
const chain = [createComponentChainLink('featuredContent', section.id)];
const basePath = 'featuredContent';
switch (section.__typename) {
case 'ProTip': {
const iconAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'icon',
componentChain: chain,
}),
`${basePath}.icon`
);
const titleAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'title',
componentChain: chain,
}),
`${basePath}.title`
);
const contentAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'content',
componentChain: chain,
}),
`${basePath}.content`
);
return (
<div>
<div {...iconAttributes}>{section.icon}</div>
<h3 {...titleAttributes}>{section.tipTitle}</h3>
<div
dangerouslySetInnerHTML={{ __html: section.tipContent.html }}
{...contentAttributes}
data-hygraph-rich-text-format="html"
/>
</div>
);
}
case 'VideoEmbed': {
const titleAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'title',
componentChain: chain,
}),
`${basePath}.title`
);
const videoUrlAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'videoUrl',
componentChain: chain,
}),
`${basePath}.videoUrl`
);
return (
<div>
<h3 {...titleAttributes}>{section.videoTitle}</h3>
<div {...videoUrlAttributes}>Video</div>
</div>
);
}
case 'IngredientSpotlight': {
const imageAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'image',
componentChain: chain,
}),
`${basePath}.image`
);
const ingredientAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'ingredient',
componentChain: chain,
}),
`${basePath}.ingredient`
);
const descriptionAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'description',
componentChain: chain,
}),
`${basePath}.description`
);
return (
<div>
<div {...imageAttributes}>Image</div>
<h3 {...ingredientAttributes}>{section.ingredient?.name}</h3>
<div
dangerouslySetInnerHTML={{ __html: section.ingredientDescription.html }}
{...descriptionAttributes}
data-hygraph-rich-text-format="html"
/>
</div>
);
}
default:
return null;
}
})()}
{recipe.additionalSections.map((section, index) => {
const chain = [createComponentChainLink('additionalSections', section.id)];
const basePath = `additionalSections.${index}`;
switch (section.__typename) {
case 'ProTip': {
const iconAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'icon',
componentChain: chain,
}),
`${basePath}.icon`
);
const titleAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'title',
componentChain: chain,
}),
`${basePath}.title`
);
const contentAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'content',
componentChain: chain,
}),
`${basePath}.content`
);
return (
<div key={section.id}>
<div {...iconAttributes}>{section.icon}</div>
<h3 {...titleAttributes}>{section.tipTitle}</h3>
<div
dangerouslySetInnerHTML={{ __html: section.tipContent.html }}
{...contentAttributes}
data-hygraph-rich-text-format="html"
/>
</div>
);
}
case 'VideoEmbed': {
const titleAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'title',
componentChain: chain,
}),
`${basePath}.title`
);
return (
<div key={section.id}>
<h3 {...titleAttributes}>{section.videoTitle}</h3>
</div>
);
}
case 'IngredientSpotlight': {
const imageAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'image',
componentChain: chain,
}),
`${basePath}.image`
);
const ingredientAttributes = withFieldPath(
createPreviewAttributes({
entryId: recipe.id,
fieldApiId: 'ingredient',
componentChain: chain,
}),
`${basePath}.ingredient`
);
return (
<div key={section.id}>
<div {...imageAttributes}>Image</div>
<h3 {...ingredientAttributes}>{section.ingredient?.name}</h3>
</div>
);
}
default:
return null;
}
})}