1 | var __rest = (this && this.__rest) || function (s, e) {
|
2 | var t = {};
|
3 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
4 | t[p] = s[p];
|
5 | if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
6 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
7 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
8 | t[p[i]] = s[p[i]];
|
9 | }
|
10 | return t;
|
11 | };
|
12 | import { h, createContext, Fragment } from "preact";
|
13 | import { useRef, useContext } from "preact/hooks";
|
14 | import { __DocContext } from "./document.js";
|
15 | import render, { renderToString } from "preact-render-to-string";
|
16 | export let warned = false;
|
17 | export const __SeoContext = createContext({
|
18 | seo: { current: {} },
|
19 | });
|
20 | const isComment = (node) => node.nodeType === node.COMMENT_NODE;
|
21 | const isElement = (node) => node.nodeType === node.ELEMENT_NODE;
|
22 | export const Head = ({ children }) => {
|
23 | var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
|
24 | const seo = useRef({});
|
25 | const { head } = useContext(__DocContext);
|
26 | const prevHead = useRef(null);
|
27 | render(h(__SeoContext.Provider, { value: { seo } }, children), {}, { pretty: true });
|
28 | head.current = [
|
29 | h(Fragment, null,
|
30 | h("meta", { name: "robots", content: `${((_a = seo.current.robots) === null || _a === void 0 ? void 0 : _a.noindex) ? "noindex" : "index"},${((_b = seo.current.robots) === null || _b === void 0 ? void 0 : _b.nofollow) ? "nofollow" : "follow"}` }),
|
31 | h("meta", { name: "googlebot", content: `${((_c = seo.current.robots) === null || _c === void 0 ? void 0 : _c.noindex) ? "noindex" : "index"},${((_d = seo.current.robots) === null || _d === void 0 ? void 0 : _d.nofollow) ? "nofollow" : "follow"}` }),
|
32 | seo.current.title && h("title", null, seo.current.title),
|
33 | seo.current.description && (h("meta", { name: "description", content: seo.current.description })),
|
34 | seo.current.canonical && (h("link", { rel: "canonical", href: seo.current.canonical })),
|
35 | ((_f = (_e = seo.current.openGraph) === null || _e === void 0 ? void 0 : _e.title) !== null && _f !== void 0 ? _f : seo.current.title) && (h("meta", { property: "og:title", content: (_h = (_g = seo.current.openGraph) === null || _g === void 0 ? void 0 : _g.title) !== null && _h !== void 0 ? _h : seo.current.title })),
|
36 | ((_k = (_j = seo.current.openGraph) === null || _j === void 0 ? void 0 : _j.description) !== null && _k !== void 0 ? _k : seo.current.description) && (h("meta", { property: "og:description", content: (_m = (_l = seo.current.openGraph) === null || _l === void 0 ? void 0 : _l.description) !== null && _m !== void 0 ? _m : seo.current.description })),
|
37 | ((_p = (_o = seo.current.openGraph) === null || _o === void 0 ? void 0 : _o.url) !== null && _p !== void 0 ? _p : seo.current.canonical) && (h("meta", { property: "og:url", content: (_r = (_q = seo.current.openGraph) === null || _q === void 0 ? void 0 : _q.url) !== null && _r !== void 0 ? _r : seo.current.canonical })),
|
38 | ((_s = seo.current.openGraph) === null || _s === void 0 ? void 0 : _s.type) && (h("meta", { property: "og:type", content: seo.current.openGraph.type })),
|
39 | ((_t = seo.current.images) === null || _t === void 0 ? void 0 : _t.length) &&
|
40 | seo.current.images.map((image) => (h(Fragment, null,
|
41 | image.src && h("meta", { property: "og:image", content: image.src }),
|
42 | image.alt && h("meta", { property: "og:image:alt", content: image.alt }),
|
43 | image.width && (h("meta", { property: "og:image:width", content: image.width.toString() })),
|
44 | image.height && (h("meta", { property: "og:image:height", content: image.height.toString() }))))),
|
45 | ((_u = seo.current.videos) === null || _u === void 0 ? void 0 : _u.length) &&
|
46 | seo.current.videos.map((video) => (h(Fragment, null,
|
47 | video.src && h("meta", { property: "og:video", content: video.src }),
|
48 | video.width && (h("meta", { property: "og:video:width", content: video.width.toString() })),
|
49 | video.height && (h("meta", { property: "og:video:height", content: video.height.toString() }))))),
|
50 | ((_v = seo.current.audio) === null || _v === void 0 ? void 0 : _v.length) &&
|
51 | seo.current.audio.map((audio) => (h("meta", { property: "og:video", content: audio.src }))),
|
52 | ((_w = seo.current.openGraph) === null || _w === void 0 ? void 0 : _w.locale) && (h("meta", { property: "og:locale", content: (_x = seo.current.openGraph) === null || _x === void 0 ? void 0 : _x.locale })),
|
53 | ((_z = (_y = seo.current.openGraph) === null || _y === void 0 ? void 0 : _y.altLocales) === null || _z === void 0 ? void 0 : _z.length) && ((_0 = seo.current.openGraph) === null || _0 === void 0 ? void 0 : _0.altLocales.map((locale) => (h("meta", { property: "og:locale:alternate", content: locale })))),
|
54 | ((_1 = seo.current.openGraph) === null || _1 === void 0 ? void 0 : _1.siteName) && (h("meta", { property: "og:site_name", content: (_2 = seo.current.openGraph) === null || _2 === void 0 ? void 0 : _2.siteName })),
|
55 | ((_3 = seo.current.openGraph) === null || _3 === void 0 ? void 0 : _3.type) === "profile" && (h(Fragment, null,
|
56 | ((_4 = seo.current.openGraph) === null || _4 === void 0 ? void 0 : _4.firstName) && (h("meta", { property: "profile:first_name", content: (_5 = seo.current.openGraph) === null || _5 === void 0 ? void 0 : _5.firstName })),
|
57 | ((_6 = seo.current.openGraph) === null || _6 === void 0 ? void 0 : _6.lastName) && (h("meta", { property: "profile:last_name", content: (_7 = seo.current.openGraph) === null || _7 === void 0 ? void 0 : _7.lastName })),
|
58 | ((_8 = seo.current.openGraph) === null || _8 === void 0 ? void 0 : _8.username) && (h("meta", { property: "profile:username", content: (_9 = seo.current.openGraph) === null || _9 === void 0 ? void 0 : _9.username })),
|
59 | ((_10 = seo.current.openGraph) === null || _10 === void 0 ? void 0 : _10.gender) && (h("meta", { property: "profile:gender", content: (_11 = seo.current.openGraph) === null || _11 === void 0 ? void 0 : _11.gender })))),
|
60 | ((_12 = seo.current.openGraph) === null || _12 === void 0 ? void 0 : _12.type) === "book" && (h(Fragment, null,
|
61 | ((_14 = (_13 = seo.current.openGraph) === null || _13 === void 0 ? void 0 : _13.authors) === null || _14 === void 0 ? void 0 : _14.length) && ((_15 = seo.current.openGraph) === null || _15 === void 0 ? void 0 : _15.authors.map((author) => (h("meta", { property: "book:author", content: author })))),
|
62 | ((_16 = seo.current.openGraph) === null || _16 === void 0 ? void 0 : _16.isbn) && (h("meta", { property: "book:isbn", content: (_17 = seo.current.openGraph) === null || _17 === void 0 ? void 0 : _17.isbn })),
|
63 | ((_19 = (_18 = seo.current.openGraph) === null || _18 === void 0 ? void 0 : _18.tags) === null || _19 === void 0 ? void 0 : _19.length) && ((_20 = seo.current.openGraph) === null || _20 === void 0 ? void 0 : _20.tags.map((tag) => (h("meta", { property: "book:tag", content: tag })))),
|
64 | ((_21 = seo.current.openGraph) === null || _21 === void 0 ? void 0 : _21.releaseDate) && (h("meta", { property: "profile:username", content: (_22 = seo.current.openGraph) === null || _22 === void 0 ? void 0 : _22.releaseDate.toISOString() })))),
|
65 | ((_23 = seo.current.openGraph) === null || _23 === void 0 ? void 0 : _23.type) === "article" && (h(Fragment, null,
|
66 | ((_24 = seo.current.openGraph) === null || _24 === void 0 ? void 0 : _24.publishedTime) && (h("meta", { property: "article:published_time", content: seo.current.openGraph.publishedTime.toISOString() })),
|
67 | ((_25 = seo.current.openGraph) === null || _25 === void 0 ? void 0 : _25.modifiedTime) && (h("meta", { property: "article:modified_time", content: seo.current.openGraph.modifiedTime.toISOString() })),
|
68 | ((_26 = seo.current.openGraph) === null || _26 === void 0 ? void 0 : _26.expirationTime) && (h("meta", { property: "article:expiration_time", content: seo.current.openGraph.expirationTime.toISOString() })),
|
69 | ((_28 = (_27 = seo.current.openGraph) === null || _27 === void 0 ? void 0 : _27.authors) === null || _28 === void 0 ? void 0 : _28.length) && ((_29 = seo.current.openGraph) === null || _29 === void 0 ? void 0 : _29.authors.map((author) => (h("meta", { property: "article:author", content: author })))),
|
70 | seo.current.openGraph.section && (h("meta", { property: "article:section", content: seo.current.openGraph.section })),
|
71 | ((_30 = seo.current.openGraph.tags) === null || _30 === void 0 ? void 0 : _30.length) &&
|
72 | seo.current.openGraph.tags.map((tag) => (h("meta", { property: "article:tag", content: tag }))))),
|
73 | ((_31 = seo.current.facebook) === null || _31 === void 0 ? void 0 : _31.appId) && (h("meta", { property: "fb:app_id", content: seo.current.facebook.appId })),
|
74 | seo.current.twitter && (h(Fragment, null,
|
75 | seo.current.twitter.card && (h("meta", { name: "twitter:card", content: seo.current.twitter.card })),
|
76 | seo.current.twitter.handle && (h("meta", { name: "twitter:creator", content: `@${seo.current.twitter.handle}`.replace(/^@@/, "@") })),
|
77 | seo.current.twitter.site && (h("meta", { name: "twitter:site", content: `@${seo.current.twitter.site}`.replace(/^@@/, "@") }))))),
|
78 | ];
|
79 | const _children = Array.isArray(children) ? children : [children];
|
80 | head.current.push(_children.map((child) => {
|
81 | if (child.type === "title" && !child.props["data-microsite-ignore"]) {
|
82 | console.warn(`Prefer microsite's built-in <seo.title> component over <title>${child.props.children}</title>`);
|
83 | if (!warned) {
|
84 | console.warn(`\nimport { seo } from 'microsite/head';\nTo suppress this wanring, pass <title data-microsite-ignore />`);
|
85 | warned = true;
|
86 | }
|
87 | }
|
88 | return child;
|
89 | }));
|
90 | if (typeof window !== "undefined") {
|
91 | if (!prevHead.current)
|
92 | document.head.prepend(document.createComment("microsite:end"));
|
93 | let html = renderToString(h(Fragment, null, head.current), {}, { pretty: true });
|
94 | if (prevHead.current !== html) {
|
95 |
|
96 | if (prevHead.current) {
|
97 | let managed = false;
|
98 | for (const node of Array.from(document.head.childNodes)) {
|
99 | if (isComment(node)) {
|
100 | if (node.nodeValue === "microsite:start") {
|
101 | managed = true;
|
102 | continue;
|
103 | }
|
104 | if (node.nodeValue === "microsite:end")
|
105 | return;
|
106 | }
|
107 | if (managed) {
|
108 | if (isElement(node) &&
|
109 | node.nextSibling &&
|
110 | isComment(node.nextSibling) &&
|
111 | node.nextSibling.nodeValue === "microsite:end") {
|
112 | node.insertAdjacentHTML("afterend", html);
|
113 | }
|
114 | node.remove();
|
115 | }
|
116 | }
|
117 | }
|
118 | }
|
119 | if (!prevHead.current) {
|
120 | const template = document.createElement("template");
|
121 | template.innerHTML = html;
|
122 | document.head.prepend(template.content.cloneNode(true));
|
123 | document.head.prepend(document.createComment("microsite:start"));
|
124 | }
|
125 | prevHead.current = html;
|
126 | }
|
127 | return null;
|
128 | };
|
129 | const normalizeChildren = (children) => {
|
130 | if (Array.isArray(children))
|
131 | return children.map(normalizeChildren).join("");
|
132 | if (["string", "number"].includes(typeof children))
|
133 | return children.toString();
|
134 | if (typeof children === "boolean")
|
135 | return children ? "" : null;
|
136 | return render(children, {});
|
137 | };
|
138 | const robots = (_a) => {
|
139 | var { children } = _a, props = __rest(_a, ["children"]);
|
140 | const { seo } = useContext(__SeoContext);
|
141 | seo.current.robots = props;
|
142 | return null;
|
143 | };
|
144 | const title = ({ children }) => {
|
145 | const { seo } = useContext(__SeoContext);
|
146 | seo.current.title = normalizeChildren(children);
|
147 | return null;
|
148 | };
|
149 | const description = ({ children }) => {
|
150 | const { seo } = useContext(__SeoContext);
|
151 | seo.current.description = normalizeChildren(children);
|
152 | return null;
|
153 | };
|
154 | const image = (_a) => {
|
155 | var _b;
|
156 | var { children } = _a, props = __rest(_a, ["children"]);
|
157 | const { seo } = useContext(__SeoContext);
|
158 | seo.current.images = [...((_b = seo.current.images) !== null && _b !== void 0 ? _b : []), props];
|
159 | return null;
|
160 | };
|
161 | const video = (_a) => {
|
162 | var _b;
|
163 | var { children } = _a, props = __rest(_a, ["children"]);
|
164 | const { seo } = useContext(__SeoContext);
|
165 | seo.current.videos = [...((_b = seo.current.videos) !== null && _b !== void 0 ? _b : []), props];
|
166 | return null;
|
167 | };
|
168 | const audio = (_a) => {
|
169 | var _b;
|
170 | var { children } = _a, props = __rest(_a, ["children"]);
|
171 | const { seo } = useContext(__SeoContext);
|
172 | seo.current.audio = [...((_b = seo.current.audio) !== null && _b !== void 0 ? _b : []), props];
|
173 | return null;
|
174 | };
|
175 | const canonical = ({ children }) => {
|
176 | const { seo } = useContext(__SeoContext);
|
177 | seo.current.canonical = normalizeChildren(children);
|
178 | return null;
|
179 | };
|
180 | const twitter = (_a) => {
|
181 | var { children } = _a, props = __rest(_a, ["children"]);
|
182 | const { seo } = useContext(__SeoContext);
|
183 | seo.current.twitter = props;
|
184 | return null;
|
185 | };
|
186 | const facebook = (_a) => {
|
187 | var { children } = _a, props = __rest(_a, ["children"]);
|
188 | const { seo } = useContext(__SeoContext);
|
189 | seo.current.facebook = props;
|
190 | return null;
|
191 | };
|
192 | const openGraph = (_a) => {
|
193 | var { children } = _a, props = __rest(_a, ["children"]);
|
194 | const { seo } = useContext(__SeoContext);
|
195 | seo.current.openGraph = props;
|
196 | return null;
|
197 | };
|
198 | export const seo = {
|
199 | robots,
|
200 | title,
|
201 | description,
|
202 | image,
|
203 | video,
|
204 | audio,
|
205 | canonical,
|
206 | twitter,
|
207 | facebook,
|
208 | openGraph,
|
209 | };
|