React components

Ready-made React components for rendering Inventra content.

The inventra/react sub-export ships React components for common content patterns so you don't have to build them yourself.

Install

Already included when you install inventra:

import { Markdown, JsonLd, AutoBreadcrumbSchema } from 'inventra/react';

<Markdown>

Renders a raw markdown string (like ContentDetail.content) as HTML. Supports GitHub-Flavored Markdown: tables, strikethrough, task lists, autolinks. Sanitizes dangerous HTML.

import { Markdown } from 'inventra/react';

<Markdown>{post.content}</Markdown>

Props

Prop Type Description
children string The markdown source.
className string Applied to the wrapper <div>. Useful for prose styling (e.g. prose prose-lg).

<JsonLd>

Embeds a JSON-LD structured data <script> for SEO. Pair it with any builder from inventra/schema:

Builder Schema type Use for
buildArticleSchema Article Blog posts, long-form content.
buildWebSiteSchema WebSite Site-wide metadata (typically rendered in the root layout).
buildProfessionalServiceSchema ProfessionalService Service businesses, agencies, consultancies.

For BreadcrumbList schemas, use the dedicated <AutoBreadcrumbSchema> component below — it reads the current path for you.

Props

Prop Type Description
data object The JSON-LD object returned from any inventra/schema builder.

buildArticleSchema

Builds an Article JSON-LD object from a ContentDetail plus your professional info.

import { JsonLd } from 'inventra/react';
import { buildArticleSchema } from 'inventra/schema';

<JsonLd
  data={buildArticleSchema({
    siteUrl: 'https://example.com',
    professional: { name: 'Acme', jobTitle: 'Agency', description: '...' },
    title: post.title,
    description: post.excerpt,
    slug: post.slug,
    publishedAt: post.publishedAt,
    authorName: post.authorName,
    featuredImageUrl: post.featuredImage?.url ?? null,
    categoryName: post.categoryName,
    tags: post.tags.map((value) => ({ value }))
  })}
/>

buildWebSiteSchema

Top-level WebSite schema. Render once in your root layout.

import { JsonLd } from 'inventra/react';
import { buildWebSiteSchema } from 'inventra/schema';

<JsonLd
  data={buildWebSiteSchema({
    siteUrl: 'https://example.com',
    professional: { name: 'Acme', jobTitle: 'Agency', description: '...' }
  })}
/>

buildProfessionalServiceSchema

ProfessionalService schema for service-business sites. Pair with a price range if relevant.

import { JsonLd } from 'inventra/react';
import { buildProfessionalServiceSchema } from 'inventra/schema';

<JsonLd
  data={buildProfessionalServiceSchema({
    siteUrl: 'https://example.com',
    professional: { name: 'Acme', jobTitle: 'Consultancy', description: '...' },
    priceRange: '$$'
  })}
/>

Multiple schemas on one page

Embed as many as you need — each renders its own <script type="application/ld+json"> tag.

<JsonLd data={buildWebSiteSchema({ siteUrl, professional })} />
<JsonLd data={buildArticleSchema({ siteUrl, professional, ...post })} />

<AutoBreadcrumbSchema>

Auto-generates a BreadcrumbList JSON-LD structure from the current pathname.

import { AutoBreadcrumbSchema } from 'inventra/react';

<AutoBreadcrumbSchema baseUrl="https://example.com" />

Props

Prop Type Description
baseUrl string Absolute base URL (no trailing slash).
pathname string Optional. Override the current path (useful for Server Components). Defaults to the current URL.

Example: article page with SEO

import { Markdown, JsonLd, AutoBreadcrumbSchema } from 'inventra/react';
import { buildArticleSchema } from 'inventra/schema';
import { Inventra } from 'inventra';

const inventra = new Inventra({
  apiKey: process.env.INVENTRA_API_KEY!,
  orgId: process.env.INVENTRA_ORG_ID!
});

export default async function BlogPost({ params }: { params: { slug: string } }) {
  const post = await inventra.contents.getBySlug(params.slug);

  return (
    <article>
      <JsonLd data={buildArticleSchema(post, { baseUrl: 'https://example.com' })} />
      <AutoBreadcrumbSchema baseUrl="https://example.com" pathname={`/blog/${post.slug}`} />
      <h1>{post.title}</h1>
      <Markdown className="prose prose-lg">{post.content}</Markdown>
    </article>
  );
}