UNPKG

@designerstrust/remix-utils

Version:

This package contains simple utility functions to use with [Remix.run](https://remix.run).

59 lines (58 loc) 2.01 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { useLocation, useMatches } from "@remix-run/react"; function isHandleStructuredData(handle) { return (handle !== undefined && handle.structuredData !== undefined && typeof handle.structuredData === "function"); } /** * Render "application/ld+json" script tags for structured data (https://developers.google.com/search/docs/advanced/structured-data/intro-structured-data) * @example * // This route uses the data to render structured data (e.g. BreadcrumbList and BlogPosting) * export let handle: HandleStructuredData<LoaderData, BlogPosting> = { * structuredData({ data }) { * let { post } = data; * * return { * '@context': 'https://schema.org', * '@type': 'BlogPosting', * datePublished: post.published, * mainEntityOfPage: { * '@type': 'WebPage', * '@id': post.postUrl, * }, * image: post.featuredImage, * author: { * '@type': 'Person', * name: post.authorName, * }, * }; * }, * }; */ export function StructuredData() { let location = useLocation(); let structuredData = useMatches().flatMap((match, index, matches) => { if (isHandleStructuredData(match.handle)) { let result = match.handle.structuredData({ id: match.id, data: match.data, params: match.params, location, parentsData: matches.slice(0, index).map((match) => match.data), }); if (result) return result; } return []; }); if (structuredData.length === 0) { return null; } let renderedScript = structuredData.length === 1 ? JSON.stringify(structuredData[0]) : JSON.stringify(structuredData); return (_jsx("script", { type: "application/ld+json", dangerouslySetInnerHTML: { __html: renderedScript, } })); }