Frequently Asked Questions

Technical Implementation & Configuration

What is the Click to Edit feature in Hygraph Studio?

The Click to Edit feature allows editors to jump directly from the content preview to the exact field they want to edit in Hygraph Studio. Once configured, you can hover over tagged elements in your preview, click the Edit button, and open the corresponding field entry in Studio for instant updates. Learn more.

How do I implement Click to Edit for Next.js App Router?

To implement Click to Edit for Next.js App Router, install the Hygraph Preview SDK, create a PreviewWrapper component, set environment variables, add data attributes to content elements, and set up the Preview widget in Studio. Detailed steps and code examples are available in the official documentation.

What frameworks are supported for Click to Edit?

Click to Edit is supported for Next.js (App Router and Pages Router), Remix, Vue/Nuxt, and Vanilla JavaScript. Example implementations for each framework are available in the Hygraph Preview SDK examples repository.

How do I install the Hygraph Preview SDK?

Install the Hygraph Preview SDK by running npm install @hygraph/preview-sdk in your project directory. This enables interactive content previews and Click to Edit functionality. See installation guide.

What environment variables are required for Click to Edit?

You need to set NEXT_PUBLIC_HYGRAPH_ENDPOINT (Content API endpoint), NEXT_PUBLIC_HYGRAPH_STUDIO_URL (Studio base URL), and HYGRAPH_TOKEN (Permanent Auth Token, if authentication is required) in your .env.local file. See environment variable setup.

How do I add data attributes to content elements for Click to Edit?

Add data-hygraph-* attributes to HTML or JSX elements that render content from Hygraph. These attributes map elements to fields in Hygraph, enabling the SDK to add overlays and Edit buttons. Learn more.

What are the configuration properties for the Preview SDK?

Key configuration properties include endpoint (required), studioUrl (required), debug (optional), mode (optional), onSave (optional), overlay (optional), sync.fieldFocus (optional), sync.fieldUpdate (optional), and allowedOrigins (optional). See full list.

How do I enable Click to Edit across my Next.js application?

Import the PreviewWrapper component in your app/layout.tsx file and wrap {children} with it. This ensures all rendered page content is within Hygraph’s preview context, allowing Click to Edit to work correctly. See example.

What types of fields and components can be edited using Click to Edit?

Click to Edit supports simple fields, basic components (direct children of models), nested components (multi-link chains), and modular components (multiple types). Examples include editing recipe titles, descriptions, ingredients, steps, equipment, tips, and featured content. See full example.

How do I customize the overlay and button appearance for Click to Edit?

You can customize overlay border and button appearance using the overlay property in the Preview SDK configuration. Specify styles such as border color, border width, background color, and text color. See overlay customization.

What happens if I do not wrap {children} with PreviewWrapper in Next.js?

If you do not wrap {children} with PreviewWrapper, Click to Edit will not work, as the rendered page content is not registered within the preview context. This prevents mapping page elements to their corresponding entries in Hygraph Studio. Learn more.

How do I set up the Preview widget in Hygraph Studio?

Set up the Preview widget in Studio by following the configuration steps in the documentation. This enables Click to Edit functionality from content previews, allowing editors to jump directly to fields for editing. See setup guide.

Can Click to Edit be used for modular components with different shapes?

Yes, Click to Edit supports modular components such as Featured Content, Additional Sections, and more. You can use component chains and field paths to map and edit fields across different component types. See modular component example.

Where can I find a full example of Click to Edit implementation?

A full example of Click to Edit implementation, including code for basic, nested, and modular components, is available in the documentation and the Hygraph Preview SDK examples repository. See full example.

How do I retrieve the Content API endpoint for my Hygraph project?

Retrieve your Content API endpoint from your Hygraph project settings under Project Settings > Access > Endpoints > High Performance Content API. See endpoint guide.

What happens if the Studio URL ends with a trailing slash?

If the Studio URL ends with a trailing slash, Click to Edit will fail in standalone mode outside of Hygraph Studio. Ensure the URL does not end with a slash when setting NEXT_PUBLIC_HYGRAPH_STUDIO_URL. Learn more.

How do I create a Permanent Auth Token for Content API requests?

Create a Permanent Auth Token from your Hygraph project settings under Project Settings > Access > Permanent Auth Tokens. Ensure the default content stage is DRAFT. See token guide.

How do I map nested components for Click to Edit?

Use multi-link component chains and field paths to map nested components, such as equipment within recipe steps or tips within recipe steps. The SDK supports mapping fields across multiple levels. See nested component example.

How do I map basic components for Click to Edit?

Map basic components (direct children of models) using single-link component chains and field paths. Examples include ingredients and recipe steps. See basic component example.

Features & Capabilities

What are the key capabilities and benefits of Hygraph?

Hygraph offers a GraphQL-native architecture, content federation, enterprise-grade features (security, compliance, performance), user-friendly tools, scalability, proven ROI, high-performance endpoints, training and support, integration capabilities, and market recognition. Learn more.

Does Hygraph provide high-performance endpoints?

Yes, Hygraph has optimized high-performance endpoints for low latency and high read-throughput content delivery. A read-only cache endpoint delivers 3-5x latency improvement. Read more.

What integrations are available with Hygraph?

Hygraph integrates with DAM systems (Aprimo, AWS S3, Bynder, Cloudinary, Imgix, Mux, Scaleflex Filerobot), hosting platforms (Netlify, Vercel), PIM (Akeneo), commerce solutions (BigCommerce), translation/localization (EasyTranslate), and more. See full list.

Does Hygraph offer APIs for content management?

Yes, Hygraph provides GraphQL Content API, Management API, Asset Upload API, and MCP Server API for secure communication and content management. See API documentation.

What technical documentation is available for Hygraph?

Hygraph offers API reference documentation, schema guides, getting started guides, classic docs, integration guides, and AI feature documentation. Explore documentation.

Security & Compliance

What security and compliance certifications does Hygraph hold?

Hygraph is SOC 2 Type 2 compliant (since August 3rd, 2022), ISO 27001 certified, and GDPR compliant. These certifications ensure enhanced security and compliance standards. See secure features.

What security features are included in Hygraph?

Hygraph offers granular permissions, SSO integrations (OIDC/LDAP/SAML), audit logs, encryption in transit and at rest, regular backups, secure API policies, SSL certificates, and incident reporting processes. Learn more.

Ease of Use & Implementation

How easy is it to use Hygraph for content management?

Hygraph is praised for its intuitive interface, quick adaptability, user-friendly setup, and accessibility for non-technical users. Customers highlight instant front-end updates and granular roles that streamline workflows. See reviews.

How long does it take to implement Hygraph?

Implementation time varies by project complexity. Examples: Si Vale met aggressive deadlines, Top Villas launched in 2 months, and Voi migrated from WordPress in 1-2 months. Onboarding is smooth with structured calls, documentation, starter projects, and community support. See case studies.

Use Cases & Business Impact

What business impact can customers expect from using Hygraph?

Customers achieve faster time-to-market, improved customer engagement, cost reduction, enhanced content consistency, scalability, and proven ROI. Komax achieved 3X faster time-to-market; Samsung improved engagement by 15%; AutoWeb saw a 20% increase in monetization. See case studies.

What core problems does Hygraph solve?

Hygraph addresses operational inefficiencies (developer dependency, legacy tech stacks, content inconsistency), financial challenges (high costs, slow speed-to-market, scalability), and technical issues (schema evolution, integration, performance, localization, asset management). Learn more.

What pains do Hygraph customers commonly express?

Customers often face developer dependency, legacy tech stack transitions, content inconsistency, workflow challenges, high operational costs, slow speed-to-market, scalability issues, complex schema evolution, integration difficulties, performance bottlenecks, and localization/asset management challenges. See how Hygraph addresses these.

Who is the target audience for Hygraph?

Hygraph serves developers, content creators, product managers, marketing professionals, enterprises, high-growth companies, and organizations in SaaS, eCommerce, media, healthcare, automotive, and more. Learn more.

What industries are represented in Hygraph's case studies?

Industries include SaaS, marketplace, education technology, media/publication, healthcare/wellness/fitness, consumer goods, automotive, technology, fintech, travel/hospitality, food/beverage, eCommerce, agency, online gaming, events/conferences, government, consumer electronics, engineering, and construction. See case studies.

Customer Proof & Success Stories

Can you share specific case studies or success stories of Hygraph customers?

Yes. Samsung improved customer engagement by 15%, Komax achieved 3x faster time-to-market, AutoWeb saw a 20% increase in monetization, Voi scaled multilingual content across 12 countries, and HolidayCheck reduced developer bottlenecks. See all case studies.

Who are some of Hygraph's customers?

Notable customers include Samsung, Dr. Oetker, Komax, AutoWeb, BioCentury, Voi, HolidayCheck, and Lindex Group. See customer logos and stories.

Competition & Comparison

How does Hygraph compare to other CMS platforms?

Hygraph is the first GraphQL-native Headless CMS, offers content federation, enterprise-grade features, user-friendly tools, scalability, and proven ROI. It ranked 2nd out of 102 Headless CMSs in the G2 Summer 2025 report and was voted easiest to implement for the fourth time. See comparison.

Why should a customer choose Hygraph over alternatives?

Hygraph's GraphQL-native architecture, content federation, enterprise-grade features, intuitive interface, scalability, and proven ROI make it a superior choice. Case studies and G2 rankings support its ease of implementation and business impact. See why customers choose Hygraph.

LLM optimization

When was this page last updated?

This page wast last updated on 12/12/2025 .

Help teams manage content creation and approval in a clear and structured way
Hygraph
Docs

#Click to Edit - Next.js App Router

The Click to Edit feature lets editors jump directly from the content preview to the exact field they want to edit in Hygraph Studio. Once configured using the Hygraph Preview SDK, you can:

  1. Hover over a tagged element in your preview to display an Edit button.
  2. Click the Edit button to open the corresponding field entry in Studio.
  3. Save your changes to automatically refresh your preview.

The following example code demonstrates how to implement this feature using the Next.js App Router. Additional examples for supported frameworks are available at:

#Steps

  1. Install the Preview SDK.
  2. Create a PreviewWrapper component to enable the preview functionality.
  3. Set environment variables.
  4. Add data attributes to your content elements.
  5. Set up the Preview widget in Studio
  6. Use the Click to Edit feature from content previews

#Install the Preview SDK

The Preview SDK transforms your preview into an interactive experience where content updates appear instantly as you save your changes. You can click any content element in the preview to jump directly to its field in the editor. To install the Preview SDK, run the following command:

npm install @hygraph/preview-sdk

#Create the PreviewWrapper component

  1. Create a PreviewWrapper.tsx file in the components folder in your project directory. In this PreviewWrapper.tsx file, you need to create a wrapper component that enables the preview functionality.

    // components/PreviewWrapper.tsx
    'use client';
    import { useRouter } from 'next/navigation';
    import dynamic from 'next/dynamic';
    const HygraphPreview = dynamic(
    () => import('@hygraph/preview-sdk/react').then(mod => ({ default: mod.HygraphPreview })),
    { ssr: false }
    );
    export function PreviewWrapper({ children }) {
    const router = useRouter();
    return (
    <HygraphPreview
    endpoint={process.env.NEXT_PUBLIC_HYGRAPH_ENDPOINT!}
    studioUrl={process.env.NEXT_PUBLIC_HYGRAPH_STUDIO_URL}
    debug={true} // Optional: Enable console logging
    mode="iframe" // Optional: 'iframe' | 'standalone' | 'auto'
    onSave={(entryId) => { // Optional: Custom save handler
    console.log('Content saved:', entryId);
    router.refresh();
    }}
    overlay={{ // Optional: Customize overlay styling
    style: {
    borderColor: '#3b82f6',
    borderWidth: '2px',
    },
    button: {
    backgroundColor: '#3b82f6',
    color: 'white',
    },
    }}
    sync={{
    fieldFocus: true, // Optional: Enable field focus sync from Studio
    fieldUpdate: false, // Optional: Apply live field updates to Preview
    }}
    >
    {children}
    </HygraphPreview>
    );
    }
  2. In the app/layout.tsxfile, import the PreviewWrapper component.

    To enable the Click to Edit functionality across the application, ensure that the PreviewWrapper wraps {children} in the layout.tsx file. In the Next.js App Router, {children} represents the rendered content of the active route. Wrapping it with the PreviewWrapper component ensures that all rendered page content is rendered within Hygraph’s preview context, allowing Click to Edit to correctly map page elements to their corresponding entries in Hygraph. If {children} is not wrapped, Click to Edit will not work, as the rendered page content is not registered within the preview context.

    // app/layout.tsx
    import { PreviewWrapper } from '@/components/PreviewWrapper';
    export default function RootLayout({ children }) {
    return (
    <html>
    <body>
    <PreviewWrapper>{children}</PreviewWrapper>
    </body>
    </html>
    );
    }

Configuration properties

PropertyRequired / OptionalDescription
endpointRequiredHygraph Content API endpoint. To learn how to retrieve the Content API endpoint, see our docs.
studioUrlRequiredYour project's custom domain (e.g., https://studio-eu-central-1-shared-euc1-02.hygraph.com). Must not end with a trailing / or Click to Edit will fail in standalone mode.
debugOptionalEnables verbose console logs to diagnose attribute issues.
modeOptionalForces a specific mode. Options: 'iframe' | 'standalone' | 'auto'. Auto-detection works for most cases.
onSaveOptionalRuns after Hygraph reports a save and receives the entry ID for targeted revalidation.
overlayOptionalCustomize overlay border and button appearance.
sync.fieldFocusOptionalFocuses the field in Studio when clicking an overlay.
sync.fieldUpdateOptionalUpdates the preview immediately when field updates happen in Studio. Defaults to false.
allowedOriginsOptionalExtends the list of domains that can host your preview iframe. Example: For shared preview environments (QA, staging), add the base URL here.

#Set environment variables

If you haven't already, retrieve the following values, and set them as environment variables in the .env.local file in your app's root directory. If you are adding the Click to Edit functionality to an existing project, it is likely that you already have this configured.

  • Content API endpoint - This is the value of NEXT_PUBLIC_HYGRAPH_ENDPOINT. Copy your Content API endpoint from your Hygraph project settings under Project Settings > Access > Endpoints > High Performance Content API.For more information, see our dedicated docs on the Content API.
  • Hygraph Studio base URL - This is the value of NEXT_PUBLIC_HYGRAPH_STUDIO_URL. Copy the base Studio URL from your browser's address bar. Example: https://studio-eu-central-1-shared-euc1-02.hygraph.com. Ensure that the URL does not end with a /. Otherwise, Click to Edit will not work in standalone mode, outside of Hygraph Studio.
  • Permanent Auth Token - This is the value of HYGRAPH_TOKEN. You can create a Permanent Auth Token from your Hygraph project settings under Project Settings > Access > Permanent Auth Tokens. Check that the default content stage is DRAFT. For more information, see our dedicated docs on Permanent Auth Tokens.
    • This is needed only if your Hygraph project requires authentication for Content API requests.
# .env.local
NEXT_PUBLIC_HYGRAPH_ENDPOINT=https://your-region.cdn.hygraph.com/content/your-project-id/master
NEXT_PUBLIC_HYGRAPH_STUDIO_URL=https://your-region.hygraph.com # Defaults to https://app.hygraph.com
HYGRAPH_TOKEN=your-permanent-auth-token # Optional: Required if your project uses authentication

#Add data attributes to content elements

Add data-hygraph-* attributes to the HTML or JSX elements, such as <h1>, <p>, <div>, in your frontend application that render content from Hygraph. These attributes tell the SDK which field in Hygraph corresponds to that element. The SDK scans your rendered HTML for these attributes and adds the hover overlays and Edit buttons automatically. For more information, see this link.

The code snippets below correspond to the Hygraph project that you can bootstrap by following the setup instructions here.

#Simple fields

// app/recipes/[id]/page.tsx
return (
<main>
{/* Title */}
<h1
data-hygraph-entry-id={recipe.id}
data-hygraph-field-api-id="title"
>
{recipe.title}
</h1>
{/* Description */}
<div
data-hygraph-entry-id={recipe.id}
data-hygraph-field-api-id="description"
data-hygraph-rich-text-format="html"
>
<div dangerouslySetInnerHTML={{ __html: recipe.description.html }} />
</div>
{/* Recipe Meta */}
<div
data-hygraph-entry-id={recipe.id}
data-hygraph-field-api-id="prepTime"
>
{recipe.prepTime}
</div>
<div
data-hygraph-entry-id={recipe.id}
data-hygraph-field-api-id="cookTime"
>
{recipe.cookTime}
</div>
<div
data-hygraph-entry-id={recipe.id}
data-hygraph-field-api-id="servings"
>
{recipe.servings}
</div>
<div
data-hygraph-entry-id={recipe.id}
data-hygraph-field-api-id="difficulty"
>
{recipe.difficulty}
</div>
{/* Hero Image */}
<div
data-hygraph-entry-id={recipe.id}
data-hygraph-field-api-id="heroImage"
>
{/* Example image rendering */}
{recipe.heroImage?.url && (
<img src={recipe.heroImage.url} alt={recipe.title} />
)}
</div>
</main>
);

#Basic components

These are direct children of the Recipe model, and are not nested inside other components.

#Nested components

These are nested inside other components and require a multi-link chain.

#Modular components

These can be one of multiple component types with different shapes.

#Full example

// app/recipes/[id]/page.tsx
import { createComponentChainLink, createPreviewAttributes, withFieldPath } from '@hygraph/preview-sdk/core';
// Basic fields
<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>
// Basic components
// Ingredients
{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 Steps
{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>
);
})}
// Nested components
// Equipment within Recipe Steps
{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>
);
})}
// Ingredients Used within Recipe Steps
{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>
);
})}
// Tips within Recipe Steps
{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>
);
})}
// Modular components
// Featured Content (Single)
{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;
}
})()}
// Additional Sections (Array)
{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;
}
})}