@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
JavaScript
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,
} }));
}