react-schemaorg
Version:
Typed Schema.org JSON-LD in React
80 lines (79 loc) • 2.82 kB
JavaScript
;
/**
* Copyright 2021 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonLd = JsonLd;
exports.jsonLdScriptProps = jsonLdScriptProps;
exports.helmetJsonLdProp = helmetJsonLdProp;
const React = require("react");
function JsonLd(props) {
return React.createElement("script", { ...jsonLdScriptProps(props.item, props) });
}
function jsonLdScriptProps(item, options = {}) {
return {
type: "application/ld+json",
dangerouslySetInnerHTML: {
__html: JSON.stringify(item, safeJsonLdReplacer, options.space),
},
};
}
function helmetJsonLdProp(item, options = {}) {
return {
type: "application/ld+json",
innerHTML: JSON.stringify(item, safeJsonLdReplacer, options.space),
};
}
const ESCAPE_ENTITIES = Object.freeze({
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'",
});
const ESCAPE_REGEX = new RegExp(`[${Object.keys(ESCAPE_ENTITIES).join("")}]`, "g");
const ESCAPE_REPLACER = (t) => ESCAPE_ENTITIES[t];
/**
* A replacer for JSON.stringify to strip JSON-LD of illegal HTML entities
* per https://www.w3.org/TR/json-ld11/#restrictions-for-contents-of-json-ld-script-elements
*/
const safeJsonLdReplacer = (() => {
// Replace per https://www.w3.org/TR/json-ld11/#restrictions-for-contents-of-json-ld-script-elements
// Solution from https://stackoverflow.com/a/5499821/864313
return (_, value) => {
switch (typeof value) {
case "object":
// Omit null values.
if (value === null) {
return undefined;
}
return value; // JSON.stringify will recursively call replacer.
case "number":
case "boolean":
case "bigint":
return value; // These values are not risky.
case "string":
return value.replace(ESCAPE_REGEX, ESCAPE_REPLACER);
default: {
// We shouldn't expect other types.
isNever(value);
// JSON.stringify will remove this element.
return undefined;
}
}
};
})();
// Utility: Assert never
function isNever(_) { }