Socket
Socket
Sign inDemoInstall

@shopify/react-html

Package Overview
Dependencies
Maintainers
11
Versions
191
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@shopify/react-html - npm Package Compare versions

Comparing version 5.0.1 to 6.0.0

dist/components/Favicon.d.ts

6

dist/common.js
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./components"));
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("./components"), exports);
var manager_1 = require("./manager");

@@ -8,0 +6,0 @@ exports.Manager = manager_1.default;

@@ -0,2 +1,6 @@

export { default as Favicon } from './Favicon';
export { default as Link } from './Link';
export { default as Meta } from './Meta';
export { default as Script } from './Script';
export { default as Style } from './Style';
export { default as Script } from './Script';
export { default as Title } from './Title';
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Favicon_1 = require("./Favicon");
exports.Favicon = Favicon_1.default;
var Link_1 = require("./Link");
exports.Link = Link_1.default;
var Meta_1 = require("./Meta");
exports.Meta = Meta_1.default;
var Script_1 = require("./Script");
exports.Script = Script_1.default;
var Style_1 = require("./Style");
exports.Style = Style_1.default;
var Script_1 = require("./Script");
exports.Script = Script_1.default;
var Title_1 = require("./Title");
exports.Title = Title_1.default;
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = __importStar(require("react"));
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
function Script(props) {
return React.createElement("script", __assign({ type: "text/javascript" }, props));
return React.createElement("script", tslib_1.__assign({ type: "text/javascript" }, props));
}
exports.default = Script;
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = __importStar(require("react"));
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
function Style(props) {
return React.createElement("link", __assign({ rel: "stylesheet", type: "text/css" }, props));
return React.createElement("link", tslib_1.__assign({ rel: "stylesheet", type: "text/css" }, props));
}
exports.default = Style;
import * as React from 'react';
import Manager from './manager';
declare const Consumer: React.ComponentType<React.ConsumerProps<Manager>>;
declare const Context: React.Context<Manager>;
interface Props {

@@ -8,3 +8,7 @@ manager?: Manager;

}
declare function HtmlManagerProvider({ manager, children }: Props): JSX.Element;
export { HtmlManagerProvider as Provider, Consumer };
declare class HtmlManagerProvider extends React.Component<Props> {
private queuedUpdate?;
componentDidMount(): void;
render(): JSX.Element;
}
export { HtmlManagerProvider as Provider, Context };
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = __importStar(require("react"));
var manager_1 = __importDefault(require("./manager"));
var _a = React.createContext(new manager_1.default()), Provider = _a.Provider, Consumer = _a.Consumer;
exports.Consumer = Consumer;
function HtmlManagerProvider(_a) {
var manager = _a.manager, children = _a.children;
return manager ? (React.createElement(Provider, { value: manager }, children)) : (React.createElement(React.Fragment, null, children));
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var manager_1 = tslib_1.__importDefault(require("./manager"));
var utilities_1 = require("./utilities");
var Context = React.createContext(new manager_1.default());
exports.Context = Context;
var HtmlManagerProvider = /** @class */ (function (_super) {
tslib_1.__extends(HtmlManagerProvider, _super);
function HtmlManagerProvider() {
return _super !== null && _super.apply(this, arguments) || this;
}
HtmlManagerProvider.prototype.componentDidMount = function () {
var _this = this;
var manager = this.props.manager;
if (manager) {
manager.subscribe(function (state) {
if (_this.queuedUpdate) {
cancelAnimationFrame(_this.queuedUpdate);
}
_this.queuedUpdate = requestAnimationFrame(function () {
updateOnClient(state);
});
});
}
};
HtmlManagerProvider.prototype.render = function () {
var _a = this.props, manager = _a.manager, children = _a.children;
return manager ? (React.createElement(Context.Provider, { value: manager }, children)) : (React.createElement(React.Fragment, null, children));
};
return HtmlManagerProvider;
}(React.Component));
exports.Provider = HtmlManagerProvider;
function updateOnClient(state) {
var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e;
var title = state.title, metas = state.metas, links = state.links;
var titleElement = document.querySelector('title');
if (title == null) {
if (titleElement) {
titleElement.remove();
}
return;
}
if (titleElement == null) {
titleElement = document.createElement('title');
document.head.appendChild(titleElement);
}
titleElement.setAttribute(utilities_1.MANAGED_ATTRIBUTE, 'true');
titleElement.textContent = title;
var fragment = document.createDocumentFragment();
try {
for (var metas_1 = tslib_1.__values(metas), metas_1_1 = metas_1.next(); !metas_1_1.done; metas_1_1 = metas_1.next()) {
var meta = metas_1_1.value;
var element = document.createElement('meta');
element.setAttribute(utilities_1.MANAGED_ATTRIBUTE, 'true');
try {
for (var _f = tslib_1.__values(Object.entries(meta)), _g = _f.next(); !_g.done; _g = _f.next()) {
var _h = tslib_1.__read(_g.value, 2), attribute = _h[0], value = _h[1];
element.setAttribute(attribute, value);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
}
finally { if (e_2) throw e_2.error; }
}
fragment.appendChild(element);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (metas_1_1 && !metas_1_1.done && (_a = metas_1.return)) _a.call(metas_1);
}
finally { if (e_1) throw e_1.error; }
}
try {
for (var links_1 = tslib_1.__values(links), links_1_1 = links_1.next(); !links_1_1.done; links_1_1 = links_1.next()) {
var link = links_1_1.value;
var element = document.createElement('link');
element.setAttribute(utilities_1.MANAGED_ATTRIBUTE, 'true');
try {
for (var _j = tslib_1.__values(Object.entries(link)), _k = _j.next(); !_k.done; _k = _j.next()) {
var _l = tslib_1.__read(_k.value, 2), attribute = _l[0], value = _l[1];
element.setAttribute(attribute, value);
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (_k && !_k.done && (_d = _j.return)) _d.call(_j);
}
finally { if (e_4) throw e_4.error; }
}
fragment.appendChild(element);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (links_1_1 && !links_1_1.done && (_c = links_1.return)) _c.call(links_1);
}
finally { if (e_3) throw e_3.error; }
}
try {
for (var _m = tslib_1.__values(document.querySelectorAll("meta[" + utilities_1.MANAGED_ATTRIBUTE + "], link[" + utilities_1.MANAGED_ATTRIBUTE + "]")), _o = _m.next(); !_o.done; _o = _m.next()) {
var node = _o.value;
node.remove();
}
}
catch (e_5_1) { e_5 = { error: e_5_1 }; }
finally {
try {
if (_o && !_o.done && (_e = _m.return)) _e.call(_m);
}
finally { if (e_5) throw e_5.error; }
}
document.head.appendChild(fragment);
}
exports.Provider = HtmlManagerProvider;
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./common"));
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("./common"), exports);

@@ -0,10 +1,41 @@

/// <reference types="react" />
export interface State {
title?: string;
metas: React.HTMLProps<HTMLMetaElement>[];
links: React.HTMLProps<HTMLLinkElement>[];
}
interface Subscription {
(state: State): void;
}
export default class Manager {
private isServer;
private serializations;
set(id: string, data: unknown): void;
get<T>(id: string): T | undefined;
private titles;
private metas;
private links;
private subscriptions;
readonly state: State;
constructor({ isServer }?: {
isServer?: boolean | undefined;
});
subscribe(subscription: Subscription): void;
addTitle(title: string): any;
addMeta(meta: React.HTMLProps<HTMLMetaElement>): any;
addLink(link: React.HTMLProps<HTMLLinkElement>): any;
setSerialization(id: string, data: unknown): void;
getSerialization<T>(id: string): T | undefined;
extract(): {
id: string;
data: unknown;
}[];
serializations: {
id: string;
data: unknown;
}[];
title?: string | undefined;
metas: import("react").HTMLProps<HTMLMetaElement>[];
links: import("react").HTMLProps<HTMLLinkElement>[];
};
private updateSubscriptions;
private removeTitle;
private removeMeta;
private removeLink;
}
export {};
"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread) || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var utilities_1 = require("./utilities");
var Manager = /** @class */ (function () {
function Manager() {
this.isServer = typeof document === 'undefined';
function Manager(_a) {
var _b = (_a === void 0 ? {} : _a).isServer, isServer = _b === void 0 ? typeof document === 'undefined' : _b;
this.serializations = utilities_1.getSerializationsFromDocument();
this.titles = [];
this.metas = [];
this.links = [];
this.subscriptions = new Set();
this.isServer = isServer;
}
Manager.prototype.set = function (id, data) {
Object.defineProperty(Manager.prototype, "state", {
get: function () {
var lastTitle = this.titles[this.titles.length - 1];
return {
title: lastTitle && lastTitle.title,
metas: this.metas,
links: this.links,
};
},
enumerable: true,
configurable: true
});
Manager.prototype.subscribe = function (subscription) {
this.subscriptions.add(subscription);
};
Manager.prototype.addTitle = function (title) {
var titleObject = { title: title };
this.titles.push(titleObject);
this.updateSubscriptions();
return this.removeTitle.bind(this, titleObject);
};
Manager.prototype.addMeta = function (meta) {
this.metas.push(meta);
this.updateSubscriptions();
return this.removeMeta.bind(this, meta);
};
Manager.prototype.addLink = function (link) {
this.links.push(link);
this.updateSubscriptions();
return this.removeLink.bind(this, link);
};
Manager.prototype.setSerialization = function (id, data) {
if (this.isServer) {

@@ -34,16 +51,53 @@ this.serializations.set(id, data);

};
Manager.prototype.get = function (id) {
Manager.prototype.getSerialization = function (id) {
return this.serializations.get(id);
};
Manager.prototype.extract = function () {
return __spread(this.serializations.entries()).map(function (_a) {
var _b = __read(_a, 2), id = _b[0], data = _b[1];
return ({
id: id,
data: data,
});
});
return tslib_1.__assign({}, this.state, { serializations: tslib_1.__spread(this.serializations.entries()).map(function (_a) {
var _b = tslib_1.__read(_a, 2), id = _b[0], data = _b[1];
return ({
id: id,
data: data,
});
}) });
};
Manager.prototype.updateSubscriptions = function () {
var e_1, _a;
try {
for (var _b = tslib_1.__values(this.subscriptions), _c = _b.next(); !_c.done; _c = _b.next()) {
var subscription = _c.value;
subscription(this.state);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
};
Manager.prototype.removeTitle = function (title) {
var index = this.titles.indexOf(title);
if (index >= 0) {
this.titles.splice(index, 1);
this.updateSubscriptions();
}
};
Manager.prototype.removeMeta = function (meta) {
var index = this.metas.indexOf(meta);
if (index >= 0) {
this.metas.splice(index, 1);
this.updateSubscriptions();
}
};
Manager.prototype.removeLink = function (link) {
var index = this.links.indexOf(link);
if (index >= 0) {
this.links.splice(index, 1);
this.updateSubscriptions();
}
};
return Manager;
}());
exports.default = Manager;
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = __importStar(require("react"));
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var react_effect_1 = require("@shopify/react-effect");

@@ -17,7 +11,7 @@ var context_1 = require("./context");

var data = _a.data;
return (React.createElement(context_1.Consumer, null, function (manager) { return (React.createElement(react_effect_1.Effect, { serverOnly: true, kind: exports.EXTRACT_ID, perform: function () { return manager.set(id, data()); } })); }));
return (React.createElement(context_1.Context.Consumer, null, function (manager) { return (React.createElement(react_effect_1.Effect, { serverOnly: true, kind: exports.EXTRACT_ID, perform: function () { return manager.setSerialization(id, data()); } })); }));
}
function WithSerialized(_a) {
var children = _a.children;
return React.createElement(context_1.Consumer, null, function (manager) { return children(manager.get(id)); });
return (React.createElement(context_1.Context.Consumer, null, function (manager) { return children(manager.getSerialization(id)); }));
}

@@ -24,0 +18,0 @@ return { Serialize: Serialize, WithSerialized: WithSerialized };

"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = __importStar(require("react"));
var react_helmet_1 = __importDefault(require("react-helmet"));
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var server_1 = require("react-dom/server");
var components_1 = require("../../components");
var Serialize_1 = __importDefault(require("./Serialize"));
var utilities_1 = require("../../utilities");
var Serialize_1 = tslib_1.__importDefault(require("./Serialize"));
function Html(_a) {
var manager = _a.manager, children = _a.children, _b = _a.locale, locale = _b === void 0 ? 'en' : _b, _c = _a.blockingScripts, blockingScripts = _c === void 0 ? [] : _c, _d = _a.scripts, scripts = _d === void 0 ? [] : _d, _e = _a.styles, styles = _e === void 0 ? [] : _e, _f = _a.headMarkup, headMarkup = _f === void 0 ? null : _f, _g = _a.bodyMarkup, bodyMarkup = _g === void 0 ? null : _g;
var _h;
var markup = server_1.renderToString(children);
var helmet = react_helmet_1.default.renderStatic();
var htmlAttributes = helmet.htmlAttributes.toComponent();
var bodyAttributes = helmet.bodyAttributes.toComponent();
var serializationMarkup = manager
? manager
.extract()
.map(function (_a) {
var extracted = manager && manager.extract();
var serializationMarkup = extracted
? extracted.serializations.map(function (_a) {
var id = _a.id, data = _a.data;
return React.createElement(Serialize_1.default, { key: id, id: id, data: data });
return (React.createElement(Serialize_1.default, { key: id, id: id, data: data }));
})
: null;
var managedProps = (_h = {}, _h[utilities_1.MANAGED_ATTRIBUTE] = true, _h);
var titleMarkup = extracted && extracted.title ? (React.createElement("title", tslib_1.__assign({}, managedProps), extracted.title)) : null;
var metaMarkup = extracted
? extracted.metas.map(function (metaProps, index) { return (
// This is never re-rendered, since it is the initial HTML document,
// so index keys are acceptable.
// eslint-disable-next-line react/no-array-index-key
React.createElement("meta", tslib_1.__assign({ key: index }, managedProps, metaProps))); })
: null;
var linkMarkup = extracted
? extracted.links.map(function (linkProps, index) { return (
// This is never re-rendered, since it is the initial HTML document,
// so index keys are acceptable.
// eslint-disable-next-line react/no-array-index-key
React.createElement("link", tslib_1.__assign({ key: index }, managedProps, linkProps))); })
: null;
var stylesMarkup = styles.map(function (style) {

@@ -55,12 +48,11 @@ return (React.createElement(components_1.Style, { key: style.path, href: style.path, integrity: style.integrity, crossOrigin: "anonymous" }));

process.env.NODE_ENV === 'development' ? { display: 'none' } : undefined;
return (React.createElement("html", __assign({ lang: locale }, htmlAttributes),
return (React.createElement("html", { lang: locale },
React.createElement("head", null,
helmet.title.toComponent(),
helmet.meta.toComponent(),
helmet.script.toComponent(),
helmet.link.toComponent(),
titleMarkup,
metaMarkup,
linkMarkup,
stylesMarkup,
headMarkup,
blockingScriptsMarkup),
React.createElement("body", __assign({}, bodyAttributes, { style: bodyStyles }),
React.createElement("body", { style: bodyStyles },
React.createElement("div", { id: "app", dangerouslySetInnerHTML: { __html: markup } }),

@@ -67,0 +59,0 @@ bodyMarkup,

"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = __importStar(require("react"));
var serialize_javascript_1 = __importDefault(require("serialize-javascript"));
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var serialize_javascript_1 = tslib_1.__importDefault(require("serialize-javascript"));
var utilities_1 = require("../../utilities");

@@ -30,4 +10,4 @@ function Serialize(_a) {

var _b;
return (React.createElement("script", __assign({ type: "text/json", dangerouslySetInnerHTML: { __html: serialize_javascript_1.default(data) } }, (_b = {}, _b[utilities_1.SERIALIZE_ATTRIBUTE] = id, _b))));
return (React.createElement("script", tslib_1.__assign({ type: "text/json", dangerouslySetInnerHTML: { __html: serialize_javascript_1.default(data) } }, (_b = {}, _b[utilities_1.SERIALIZE_ATTRIBUTE] = id, _b))));
}
exports.default = Serialize;
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("../common"));
__export(require("./components"));
__export(require("./utilities"));
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("../common"), exports);
tslib_1.__exportStar(require("./components"), exports);
tslib_1.__exportStar(require("./utilities"), exports);
export declare const SERIALIZE_ATTRIBUTE = "data-serialized-id";
export declare const MANAGED_ATTRIBUTE = "data-react-html";
export declare const EFFECT_ID: unique symbol;
export declare function getSerializationsFromDocument(): Map<string, unknown>;
export declare function getSerialized<Data>(id: string): Data | undefined;
export declare function showPage(): Promise<void>;
"use strict";
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
exports.SERIALIZE_ATTRIBUTE = 'data-serialized-id';
exports.MANAGED_ATTRIBUTE = 'data-react-html';
exports.EFFECT_ID = Symbol('html');
function getSerializationsFromDocument() {

@@ -21,3 +14,3 @@ var e_1, _a;

try {
for (var _b = __values(document.querySelectorAll("[" + exports.SERIALIZE_ATTRIBUTE + "]")), _c = _b.next(); !_c.done; _c = _b.next()) {
for (var _b = tslib_1.__values(document.querySelectorAll("[" + exports.SERIALIZE_ATTRIBUTE + "]")), _c = _b.next(); !_c.done; _c = _b.next()) {
var node = _c.value;

@@ -24,0 +17,0 @@ serializations.set(

{
"name": "@shopify/react-html",
"version": "5.0.1",
"version": "6.0.0",
"license": "MIT",

@@ -26,4 +26,3 @@ "description": "A component to render your react app with no static HTML.",

"dependencies": {
"@shopify/react-serialize": "^1.0.10",
"react-helmet": "^5.2.0"
"@shopify/react-serialize": "^1.0.10"
},

@@ -30,0 +29,0 @@ "peerDependencies": {

@@ -41,3 +41,3 @@ # `@shopify/react-html`

The component will automatically propagate any usage of the [`react-helmet` library](https://github.com/nfl/react-helmet) in your app’s content to manipulate the title or other top level HTML or HEAD attributes. If you want to make use of the serialization techniques [documented below](#in-your-app-code), you must also construct a `Manager` instance, pass it to a `<Provider />` component, and call `@shopify/react-effect`’s `extract` method:
If you want to make use of the serialization techniques [documented below](#in-your-app-code), you must also construct a `Manager` instance, pass it to a `<Provider />` component, and call `@shopify/react-effect`’s `extract` method:

@@ -208,2 +208,24 @@ ```tsx

### `<Link />`
Renders a `<link />` tag in the head with the specified attributes. On the server, links are recorded in the `Manager` and automatically applied to the `Html` component. On the client, the `<link />` tags are updated in a deferred callback to minimize DOM manipulations.
The `<Link />` component accepts any properties you would supply to a `<link />` tag. If you are using this component to create a favicon, use the [`<Favicon />`](#favicon) component instead.
### `<Meta />`
Renders a `<meta />` tag in the head with the specified attributes. This component uses the same approach to render these tags as detailed for the `<Link />` component above.
The `<Meta />` component accepts any properties you would supply to a `<meta />` tag.
### `<Title />`
Renders a `<title />` tag in the head with the specified attributes. If multiple `<Title />` components are rendered in your app, the last one (usually, the most deeply nested) will be applied.
This component accepts a string child, which will be used to set the title of the page.
### `<Favicon />`
Renders a `<link />` tag with the necessary props to specify a favicon. Accepts a `source` property that should be the image source for the favicon.
### `<Serialize />`

@@ -210,0 +232,0 @@

@@ -0,2 +1,6 @@

export {default as Favicon} from './Favicon';
export {default as Link} from './Link';
export {default as Meta} from './Meta';
export {default as Script} from './Script';
export {default as Style} from './Style';
export {default as Script} from './Script';
export {default as Title} from './Title';
import {getSerializationsFromDocument} from './utilities';
interface Title {
title: string;
}
export interface State {
title?: string;
metas: React.HTMLProps<HTMLMetaElement>[];
links: React.HTMLProps<HTMLLinkElement>[];
}
interface Subscription {
(state: State): void;
}
export default class Manager {
private isServer = typeof document === 'undefined';
private isServer: boolean;
private serializations = getSerializationsFromDocument();
private titles: Title[] = [];
private metas: React.HTMLProps<HTMLMetaElement>[] = [];
private links: React.HTMLProps<HTMLLinkElement>[] = [];
private subscriptions = new Set<Subscription>();
set(id: string, data: unknown) {
get state(): State {
const lastTitle = this.titles[this.titles.length - 1];
return {
title: lastTitle && lastTitle.title,
metas: this.metas,
links: this.links,
};
}
constructor({isServer = typeof document === 'undefined'} = {}) {
this.isServer = isServer;
}
subscribe(subscription: Subscription) {
this.subscriptions.add(subscription);
}
addTitle(title: string) {
const titleObject = {title};
this.titles.push(titleObject);
this.updateSubscriptions();
return this.removeTitle.bind(this, titleObject);
}
addMeta(meta: React.HTMLProps<HTMLMetaElement>) {
this.metas.push(meta);
this.updateSubscriptions();
return this.removeMeta.bind(this, meta);
}
addLink(link: React.HTMLProps<HTMLLinkElement>) {
this.links.push(link);
this.updateSubscriptions();
return this.removeLink.bind(this, link);
}
setSerialization(id: string, data: unknown) {
if (this.isServer) {

@@ -13,3 +68,3 @@ this.serializations.set(id, data);

get<T>(id: string): T | undefined {
getSerialization<T>(id: string): T | undefined {
return this.serializations.get(id) as T | undefined;

@@ -19,7 +74,40 @@ }

extract() {
return [...this.serializations.entries()].map(([id, data]) => ({
id,
data,
}));
return {
...this.state,
serializations: [...this.serializations.entries()].map(([id, data]) => ({
id,
data,
})),
};
}
private updateSubscriptions() {
for (const subscription of this.subscriptions) {
subscription(this.state);
}
}
private removeTitle(title: Title) {
const index = this.titles.indexOf(title);
if (index >= 0) {
this.titles.splice(index, 1);
this.updateSubscriptions();
}
}
private removeMeta(meta: React.HTMLProps<HTMLMetaElement>) {
const index = this.metas.indexOf(meta);
if (index >= 0) {
this.metas.splice(index, 1);
this.updateSubscriptions();
}
}
private removeLink(link: React.HTMLProps<HTMLLinkElement>) {
const index = this.links.indexOf(link);
if (index >= 0) {
this.links.splice(index, 1);
this.updateSubscriptions();
}
}
}
export const SERIALIZE_ATTRIBUTE = 'data-serialized-id';
export const MANAGED_ATTRIBUTE = 'data-react-html';
export const EFFECT_ID = Symbol('html');

@@ -3,0 +5,0 @@ export function getSerializationsFromDocument() {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc