@anywayseo/tools 5.11.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/components/game-demo/index.d.ts +2 -6
  2. package/dist/components/index.cjs +3 -3
  3. package/dist/components/index.mjs +3 -3
  4. package/dist/components/seo/href-langs/index.d.ts +8 -0
  5. package/dist/components/seo/index.d.ts +3 -2
  6. package/dist/components/seo/json-ld/index.d.ts +7 -0
  7. package/dist/components/seo/types.d.ts +4 -3
  8. package/dist/components/seo/utils.d.ts +1 -0
  9. package/dist/components/{strapi-component → strapi-content-renderer/strapi-component}/external-image/index.d.ts +1 -1
  10. package/dist/components/{strapi-component → strapi-content-renderer/strapi-component}/index.d.ts +1 -1
  11. package/dist/components/{strapi-component → strapi-content-renderer/strapi-component}/rich-text/index.d.ts +2 -1
  12. package/dist/components/{strapi-component → strapi-content-renderer/strapi-component}/utils.d.ts +1 -1
  13. package/dist/index-0AAkKSsc.mjs +146 -0
  14. package/dist/{index-CPbWQKoT.mjs → index-B5C9u9UE.mjs} +1 -1
  15. package/dist/{index-hGzNO4AL.js → index-B5SWTYZm.js} +67 -29
  16. package/dist/index-BJsA8Upb.js +192 -0
  17. package/dist/{index-DhhGhwm2.js → index-BSAasfl2.js} +3 -4
  18. package/dist/index-BU1gLt1p.js +145 -0
  19. package/dist/{index-CG7F6SYt.mjs → index-BhzKUTPZ.mjs} +66 -28
  20. package/dist/{index-DqMBmwe5.mjs → index-C7buhUOk.mjs} +3 -4
  21. package/dist/{index-C3n63_nP.js → index-CAjUjAgI.js} +1 -1
  22. package/dist/{index-DSP348cK.mjs → index-CQC6DRGf.mjs} +1 -1
  23. package/dist/index-CUDzMwnz.mjs +193 -0
  24. package/dist/{index-Ca9tsjT8.js → index-DJSBjQzq.js} +1 -1
  25. package/dist/{index-D-jM-cHx.js → index-DZc8PJET.js} +1 -1
  26. package/dist/{index-B6wLLS6t.mjs → index-U-DmPFa7.mjs} +1 -1
  27. package/dist/index.cjs +17 -7
  28. package/dist/index.mjs +28 -18
  29. package/dist/layout/index.cjs +6 -6
  30. package/dist/layout/index.mjs +6 -6
  31. package/dist/providers/index.cjs +2 -2
  32. package/dist/providers/index.mjs +2 -2
  33. package/dist/providers/site-provider/index.d.ts +2 -1
  34. package/dist/types/api/index.d.ts +2 -16
  35. package/dist/types/api/strapi-navigation.d.ts +16 -0
  36. package/dist/types/api/strapi-page.d.ts +45 -0
  37. package/dist/types/components/game-demo/index.d.ts +5 -0
  38. package/dist/types/components/index.d.ts +1 -1
  39. package/dist/types/content/seo/index.d.ts +38 -1
  40. package/dist/types/index.d.ts +1 -1
  41. package/dist/types/json-ld/index.d.ts +162 -0
  42. package/dist/types/site/index.d.ts +9 -4
  43. package/dist/utils/api/index.d.ts +4 -2
  44. package/dist/utils/api/strapi-guards.d.ts +4 -0
  45. package/dist/utils/api/strapi-navigation.d.ts +2 -0
  46. package/dist/utils/api/strapi-seo.d.ts +13 -0
  47. package/dist/utils/index.cjs +13 -3
  48. package/dist/utils/index.d.ts +1 -0
  49. package/dist/utils/index.mjs +24 -14
  50. package/dist/utils/json-ld/index.d.ts +70 -0
  51. package/dist/utils/navigation/index.d.ts +1 -1
  52. package/package.json +1 -1
  53. package/dist/components/strapi-content-renderer/utils.d.ts +0 -2
  54. package/dist/index-Ba_pXx_e.js +0 -97
  55. package/dist/index-BeJTy4iY.mjs +0 -26
  56. package/dist/index-BfITsKAr.js +0 -25
  57. package/dist/index-CJANSiM5.mjs +0 -98
  58. package/dist/types/components/strapi-component/index.d.ts +0 -5
  59. package/dist/types/page/index.d.ts +0 -7
@@ -1,5 +1,5 @@
1
1
  import { FC, ReactElement } from 'react';
2
- import { BoxPositionProps, ImageFit } from '../../types';
2
+ import { BoxPositionProps, IGameDemo, ImageFit } from '../../types';
3
3
  type GamePreviewImageProps = {
4
4
  previewImage: string;
5
5
  previewImageFit?: ImageFit;
@@ -7,10 +7,6 @@ type GamePreviewImageProps = {
7
7
  previewImage: ReactElement;
8
8
  previewImageFit?: never;
9
9
  };
10
- type GameDemoProps = {
11
- name: string;
12
- src?: string;
13
- refLink?: string;
14
- } & BoxPositionProps & GamePreviewImageProps;
10
+ type GameDemoProps = IGameDemo & GamePreviewImageProps & BoxPositionProps;
15
11
  declare const GameDemo: FC<GameDemoProps>;
16
12
  export default GameDemo;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const index = require("../index-hGzNO4AL.js");
4
- const index$1 = require("../index-DhhGhwm2.js");
3
+ const index = require("../index-B5SWTYZm.js");
4
+ const index$1 = require("../index-BSAasfl2.js");
5
5
  const index$2 = require("../index-DDg_PkD2.js");
6
- const index$3 = require("../index-D-jM-cHx.js");
6
+ const index$3 = require("../index-DZc8PJET.js");
7
7
  exports.ActionButton = index.ActionButton;
8
8
  exports.ArticleCard = index.ArticleCard;
9
9
  exports.ArticleCardGrid = index.ArticleCardGrid;
@@ -1,7 +1,7 @@
1
- import { A, a, b, c, n, o, d, B, e, C, r, q, F, f, g, G, h, i, j, p, H, I, L, N, s, P, S, k, T, l, t, m } from "../index-CG7F6SYt.mjs";
2
- import { C as C2, a as a2, b as b2, L as L2, c as c2, R, S as S2, d as d2 } from "../index-DqMBmwe5.mjs";
1
+ import { A, a, b, c, n, o, d, B, e, C, r, q, F, f, g, G, h, i, j, p, H, I, L, N, s, P, S, k, T, l, t, m } from "../index-BhzKUTPZ.mjs";
2
+ import { C as C2, a as a2, b as b2, L as L2, c as c2, R, S as S2, d as d2 } from "../index-C7buhUOk.mjs";
3
3
  import { H as H2, a as a3, b as b3, O, P as P2, U } from "../index-BEjKnOZA.mjs";
4
- import { I as I2, L as L3 } from "../index-B6wLLS6t.mjs";
4
+ import { I as I2, L as L3 } from "../index-U-DmPFa7.mjs";
5
5
  export {
6
6
  A as ActionButton,
7
7
  a as ArticleCard,
@@ -0,0 +1,8 @@
1
+ import { FC } from 'react';
2
+ import { IHrefLang } from '../../../types';
3
+ type HrefLangsProps = {
4
+ siteName: string;
5
+ hrefLangs: IHrefLang[];
6
+ };
7
+ declare const HrefLangs: FC<HrefLangsProps>;
8
+ export default HrefLangs;
@@ -1,12 +1,13 @@
1
1
  import { FC, PropsWithChildren } from 'react';
2
- import { SeoCanonical, SeoDescription, SeoHrefLangs, SeoLocale, SeoTitle } from './types';
2
+ import { SeoCanonical, SeoDescription, SeoHrefLangs, SeoLocale, SeoStructuredData, SeoTitle } from './types';
3
3
  type SeoProps = PropsWithChildren<{
4
4
  pathname: Location['pathname'];
5
5
  locale?: SeoLocale;
6
6
  title?: SeoTitle;
7
7
  description?: SeoDescription;
8
- canonical?: SeoCanonical;
8
+ canonicalUrl?: SeoCanonical;
9
9
  hrefLangs?: SeoHrefLangs;
10
+ structuredData?: SeoStructuredData;
10
11
  }>;
11
12
  declare const Seo: FC<SeoProps>;
12
13
  export default Seo;
@@ -0,0 +1,7 @@
1
+ import { FC } from 'react';
2
+ import { Schemas } from '../../../types';
3
+ type JsonLdProps = {
4
+ schemas: Schemas;
5
+ };
6
+ declare const JsonLd: FC<JsonLdProps>;
7
+ export default JsonLd;
@@ -1,4 +1,4 @@
1
- import { IHrefLang, ILocale, ISeo, Nullable } from '../../types';
1
+ import { IHrefLang, ILocale, ISeoMetadata, IStructuredData, Nullable } from '../../types';
2
2
  export interface ISeoMetaItemPlaceholders {
3
3
  siteName: string;
4
4
  currentYear: string;
@@ -6,8 +6,9 @@ export interface ISeoMetaItemPlaceholders {
6
6
  }
7
7
  type SeoMetaItemGetter = (placeholders: ISeoMetaItemPlaceholders) => string;
8
8
  export type SeoLocale = Nullable<ILocale['code']>;
9
- export type SeoTitle = Nullable<ISeo['title'] | SeoMetaItemGetter>;
10
- export type SeoDescription = Nullable<ISeo['description'] | SeoMetaItemGetter>;
9
+ export type SeoTitle = Nullable<ISeoMetadata['title'] | SeoMetaItemGetter>;
10
+ export type SeoDescription = Nullable<ISeoMetadata['description'] | SeoMetaItemGetter>;
11
11
  export type SeoCanonical = Nullable<string>;
12
12
  export type SeoHrefLangs = IHrefLang[];
13
+ export type SeoStructuredData = Nullable<IStructuredData>;
13
14
  export {};
@@ -1,2 +1,3 @@
1
1
  import { ISeoMetaItemPlaceholders, SeoDescription, SeoTitle } from './types';
2
+ export declare function buildPlaceholders(siteName: string, lang: string): ISeoMetaItemPlaceholders;
2
3
  export declare function getSeoMetaItem<T extends SeoTitle | SeoDescription>(item: NonNullable<T>, placeholders: ISeoMetaItemPlaceholders): string;
@@ -1,5 +1,5 @@
1
1
  import { FC } from 'react';
2
- import { IGatsbyImageFile, ExternalImageComponent, ExternalImageComponentProps } from '../../../types';
2
+ import { IGatsbyImageFile, ExternalImageComponent, ExternalImageComponentProps } from '../../../../types';
3
3
  type ExternalImageProps = ExternalImageComponentProps<IGatsbyImageFile> & {
4
4
  component: ExternalImageComponent;
5
5
  };
@@ -1,5 +1,5 @@
1
1
  import { FC } from 'react';
2
- import { StrapiComponentType, ExternalImageComponent } from '../../types';
2
+ import { StrapiComponentType, ExternalImageComponent } from '../../../types';
3
3
  type StrapiComponentProps = {
4
4
  type: StrapiComponentType;
5
5
  props: any;
@@ -1,6 +1,7 @@
1
1
  import { FC } from 'react';
2
+ import { IStrapiRichText } from '../../../../types';
2
3
  type RichTextProps = {
3
- content: string;
4
+ content: IStrapiRichText['data']['content'];
4
5
  };
5
6
  declare const RichText: FC<RichTextProps>;
6
7
  export default RichText;
@@ -1,4 +1,4 @@
1
- import { Currency } from '../../types';
1
+ import { Currency } from '../../../types';
2
2
  export declare function extractItemsFromJson(content: {
3
3
  ['strapi_json_value']: string[];
4
4
  }): string[];
@@ -0,0 +1,146 @@
1
+ import { DEFAULT_LANGUAGE } from "./i18n/index.mjs";
2
+ function isStrapiContent(array) {
3
+ return Array.isArray(array) && array.every(
4
+ (item) => typeof item === "object" && item !== null && "__typename" in item && typeof item.__typename === "string"
5
+ );
6
+ }
7
+ function isStrapiPageData(data) {
8
+ const maybe = data;
9
+ return Boolean(typeof data === "object" && maybe.content);
10
+ }
11
+ function isStrapiPageContext(context) {
12
+ const maybe = context;
13
+ return Boolean(typeof context === "object" && maybe.hrefLangs);
14
+ }
15
+ function getCurrencySymbol(currencyCode, locale = DEFAULT_LANGUAGE) {
16
+ const symbol = 0 .toLocaleString(locale, {
17
+ style: "currency",
18
+ currency: currencyCode,
19
+ minimumFractionDigits: 0,
20
+ maximumFractionDigits: 0
21
+ }).replace(/\d/g, "").trim();
22
+ return symbol;
23
+ }
24
+ function buildGraph(schemas) {
25
+ return Object.values(schemas);
26
+ }
27
+ const id = {
28
+ organization: (siteUrl) => `${siteUrl}/#organization`,
29
+ website: (siteUrl) => `${siteUrl}/#website`,
30
+ webpage: (pageUrl) => `${pageUrl}`,
31
+ review: (pageUrl) => `${pageUrl}#review`,
32
+ game: (pageUrl) => `${pageUrl}#game`,
33
+ author: (authorPageUrl) => `${authorPageUrl}#person`
34
+ };
35
+ function buildOrganizationSchema(params) {
36
+ const { site, lang } = params;
37
+ const logoUrl = `${site.url}${site.logo.url}`;
38
+ return {
39
+ "@type": "Organization",
40
+ "@id": id.organization(site.url),
41
+ name: site.name,
42
+ url: site.url,
43
+ logo: {
44
+ "@type": "ImageObject",
45
+ url: logoUrl,
46
+ contentUrl: logoUrl,
47
+ width: site.logo.width,
48
+ height: site.logo.height,
49
+ caption: site.logo.alt,
50
+ inLanguage: lang
51
+ }
52
+ };
53
+ }
54
+ function buildWebsiteSchema(params) {
55
+ const { site, lang } = params;
56
+ return {
57
+ "@type": "WebSite",
58
+ "@id": id.website(site.url),
59
+ url: site.url,
60
+ name: site.name,
61
+ inLanguage: lang,
62
+ publisher: { "@id": id.organization(site.url) }
63
+ };
64
+ }
65
+ function getEntitySchema({ site, page, structuredData }) {
66
+ if (!structuredData) {
67
+ return null;
68
+ }
69
+ const { entity, content } = structuredData;
70
+ if (entity === "game-review" && content.review && content.game) {
71
+ return buildGameReviewSchema({ site, page, author: content.author, review: content.review, game: content.game });
72
+ }
73
+ return null;
74
+ }
75
+ function buildWebpageSchema(params, mainEntity) {
76
+ const { site, page, lang } = params;
77
+ return {
78
+ "@type": "WebPage",
79
+ "@id": id.webpage(page.url),
80
+ url: page.url,
81
+ name: page.title,
82
+ ...page.description ? { description: page.description } : {},
83
+ inLanguage: lang,
84
+ isPartOf: { "@id": id.website(site.url) },
85
+ ...mainEntity ? { mainEntity } : {}
86
+ };
87
+ }
88
+ function buildGameReviewSchema(params) {
89
+ const { site, page, author, review, game } = params;
90
+ return {
91
+ "@type": "Review",
92
+ "@id": id.review(page.url),
93
+ name: review.title,
94
+ reviewBody: review.description,
95
+ ...author ? {
96
+ author: {
97
+ "@type": "Person",
98
+ name: author.name,
99
+ ...author.url ? { "@id": id.author(author.url), url: author.url } : {}
100
+ }
101
+ } : {},
102
+ publisher: { "@id": id.organization(site.url) },
103
+ datePublished: review.publishedAt,
104
+ dateModified: review.updatedAt || review.publishedAt,
105
+ ...review.rating ? {
106
+ reviewRating: {
107
+ "@type": "Rating",
108
+ ratingValue: review.rating.value,
109
+ bestRating: review.rating.max,
110
+ worstRating: review.rating.min
111
+ }
112
+ } : {},
113
+ itemReviewed: {
114
+ "@type": "Game",
115
+ "@id": id.game(page.url),
116
+ url: page.url,
117
+ name: game.name,
118
+ ...game.genre ? { genre: game.genre } : {}
119
+ }
120
+ };
121
+ }
122
+ function randomComparator() {
123
+ return Math.random() - 0.5;
124
+ }
125
+ function seededRandom(seed) {
126
+ return Math.abs(Math.sin(seed));
127
+ }
128
+ function getSeededRandomComparator(seed) {
129
+ const safeSeed = Math.abs(seed) % Number.MAX_SAFE_INTEGER;
130
+ let index = 0;
131
+ return () => seededRandom(safeSeed + index++) - 0.5;
132
+ }
133
+ export {
134
+ isStrapiPageData as a,
135
+ isStrapiPageContext as b,
136
+ buildGraph as c,
137
+ buildOrganizationSchema as d,
138
+ buildWebsiteSchema as e,
139
+ getEntitySchema as f,
140
+ getCurrencySymbol as g,
141
+ buildWebpageSchema as h,
142
+ isStrapiContent as i,
143
+ buildGameReviewSchema as j,
144
+ getSeededRandomComparator as k,
145
+ randomComparator as r
146
+ };
@@ -2,7 +2,7 @@ import { jsx } from "react/jsx-runtime";
2
2
  import { MDXProvider } from "@mdx-js/react";
3
3
  import "react-i18next";
4
4
  import "@chakra-ui/react";
5
- import { I as Image, L as Link } from "./index-B6wLLS6t.mjs";
5
+ import { I as Image, L as Link } from "./index-U-DmPFa7.mjs";
6
6
  import "./index-BJRvnR8Q.mjs";
7
7
  import "./index-RzByAgHO.mjs";
8
8
  import "@chakra-ui/icons";
@@ -3,18 +3,18 @@ const jsxRuntime = require("react/jsx-runtime");
3
3
  const react = require("@chakra-ui/react");
4
4
  const reactI18next = require("react-i18next");
5
5
  const react$2 = require("@mdx-js/react");
6
- const index = require("./index-D-jM-cHx.js");
6
+ const index = require("./index-DZc8PJET.js");
7
7
  require("./index-C6MG_f24.js");
8
8
  const index$6 = require("./index-CBRFCYhV.js");
9
9
  const icons = require("@chakra-ui/icons");
10
10
  require("react-medium-image-zoom");
11
11
  const react$1 = require("react");
12
- const index$2 = require("./index-DhhGhwm2.js");
12
+ const index$2 = require("./index-BSAasfl2.js");
13
13
  const index$3 = require("./index-DDg_PkD2.js");
14
- const index$7 = require("./index-C3n63_nP.js");
14
+ const index$7 = require("./index-CAjUjAgI.js");
15
+ const index$5 = require("./index-BU1gLt1p.js");
15
16
  const index$1 = require("./index-ov4J7p3D.js");
16
17
  const index$4 = require("./index-CVv755RW.js");
17
- const index$5 = require("./index-BfITsKAr.js");
18
18
  const i18next = require("i18next");
19
19
  const Markdown = require("react-markdown");
20
20
  const ArticleMetaIconMap = {
@@ -693,7 +693,7 @@ const NotFound = () => {
693
693
  const CookiePolicy = () => {
694
694
  const { t } = reactI18next.useTranslation("pageCookiePolicy");
695
695
  const { metadata } = index.useSiteContext();
696
- const { name: siteName } = metadata;
696
+ const siteName = metadata.name;
697
697
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
698
698
  /* @__PURE__ */ jsxRuntime.jsx(index$3.Heading1, { children: t("title") }),
699
699
  /* @__PURE__ */ jsxRuntime.jsx(index$3.Paragraph, { children: t("text", { siteName }) }),
@@ -799,7 +799,7 @@ const Contacts = () => {
799
799
  const PrivacyPolicy = ({ contactsSlug }) => {
800
800
  const { t } = reactI18next.useTranslation("pagePrivacyPolicy");
801
801
  const { metadata } = index.useSiteContext();
802
- const { name: siteName } = metadata;
802
+ const siteName = metadata.name;
803
803
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
804
804
  /* @__PURE__ */ jsxRuntime.jsx(index$3.Heading1, { children: t("title") }),
805
805
  /* @__PURE__ */ jsxRuntime.jsx(index$3.Paragraph, { children: t("text") }),
@@ -829,7 +829,7 @@ const PrivacyPolicy = ({ contactsSlug }) => {
829
829
  const TermsAndConditions = ({ privacyPolicySlug }) => {
830
830
  const { t } = reactI18next.useTranslation("pageTermsAndConditions");
831
831
  const { metadata } = index.useSiteContext();
832
- const { name: siteName } = metadata;
832
+ const siteName = metadata.name;
833
833
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
834
834
  /* @__PURE__ */ jsxRuntime.jsx(index$3.Heading1, { children: t("title") }),
835
835
  /* @__PURE__ */ jsxRuntime.jsx(index$3.Paragraph, { children: t("text", { siteName }) }),
@@ -951,6 +951,13 @@ const ProsCons = ({ items, ...boxProps }) => {
951
951
  /* @__PURE__ */ jsxRuntime.jsx(ProsConsCard, { itemType: "cons", items: cons })
952
952
  ] });
953
953
  };
954
+ function buildPlaceholders(siteName, lang) {
955
+ return {
956
+ siteName,
957
+ currentYear: index$1.getCurrentYear(lang),
958
+ currentMonth: index$1.getCurrentMonth(lang)
959
+ };
960
+ }
954
961
  function replacePlaceholders(text, placeholders) {
955
962
  Object.entries(placeholders).forEach(([placeholder, replacement]) => {
956
963
  const regex = new RegExp(`{{${placeholder}}}`, "g");
@@ -964,25 +971,61 @@ function getSeoMetaItem(item, placeholders) {
964
971
  }
965
972
  return item(placeholders);
966
973
  }
967
- const Seo = ({ children, pathname, locale, title, description, canonical, hrefLangs = [] }) => {
968
- const { metadata: siteMetadata } = index.useSiteContext();
969
- const { name: siteName, lang: siteLocale, seo: siteSeo } = siteMetadata;
970
- const { title: siteTitle, description: siteDescription } = siteSeo;
971
- const lang = locale || siteLocale;
972
- const placeholders = react$1.useMemo(
973
- () => ({
974
- siteName,
975
- currentYear: index$1.getCurrentYear(lang),
976
- currentMonth: index$1.getCurrentMonth(lang)
977
- }),
978
- [siteName, lang]
974
+ const JsonLd = ({ schemas }) => {
975
+ const graph = index$5.buildGraph(schemas);
976
+ if (!graph.length) {
977
+ return null;
978
+ }
979
+ const jsonLd = {
980
+ "@context": "https://schema.org",
981
+ "@graph": graph
982
+ };
983
+ return /* @__PURE__ */ jsxRuntime.jsx(
984
+ "script",
985
+ {
986
+ type: "application/ld+json",
987
+ dangerouslySetInnerHTML: {
988
+ __html: JSON.stringify(jsonLd)
989
+ }
990
+ }
979
991
  );
992
+ };
993
+ const HrefLangs = ({ siteName, hrefLangs }) => {
994
+ return hrefLangs.map(({ href, hrefLang }, index2) => /* @__PURE__ */ jsxRuntime.jsx("link", { rel: "alternate", hrefLang, href: index$7.buildCanonicalUrl(siteName, href) }, index2));
995
+ };
996
+ const Seo = ({
997
+ children,
998
+ pathname,
999
+ locale,
1000
+ title,
1001
+ description,
1002
+ canonicalUrl,
1003
+ hrefLangs = [],
1004
+ structuredData
1005
+ }) => {
1006
+ const { metadata: siteMetadata, logo: siteLogo, localization } = index.useSiteContext();
1007
+ const { name: siteName, seo: siteSeo } = siteMetadata;
1008
+ const { title: defaultTitle, description: defaultDescription } = siteSeo;
1009
+ const defaultLocale = localization.defaultLocale.code;
1010
+ const lang = locale || defaultLocale;
1011
+ const placeholders = buildPlaceholders(siteName, lang);
1012
+ const siteUrl = index$7.buildCanonicalUrl(siteName);
1013
+ const pageUrl = index$7.buildCanonicalUrl(siteName, pathname);
1014
+ const pageTitle = getSeoMetaItem(title ?? defaultTitle, placeholders);
1015
+ const pageDescription = getSeoMetaItem(description ?? defaultDescription, placeholders);
1016
+ const siteData = { url: siteUrl, name: siteName, logo: siteLogo };
1017
+ const pageData = { url: pageUrl, title: pageTitle, description: pageDescription };
1018
+ const organizationSchema = index$5.buildOrganizationSchema({ site: siteData, lang });
1019
+ const websiteSchema = index$5.buildWebsiteSchema({ site: siteData, lang });
1020
+ const entitySchema = index$5.getEntitySchema({ site: siteData, page: pageData, structuredData });
1021
+ const webpageSchema = index$5.buildWebpageSchema({ site: siteData, page: pageData, lang }, entitySchema);
980
1022
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
981
1023
  /* @__PURE__ */ jsxRuntime.jsx("html", { lang }),
982
- /* @__PURE__ */ jsxRuntime.jsx("title", { children: getSeoMetaItem(title ?? siteTitle, placeholders) }),
983
- /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "description", content: getSeoMetaItem(description ?? siteDescription, placeholders) }),
984
- /* @__PURE__ */ jsxRuntime.jsx("link", { rel: "canonical", href: canonical ?? index$7.buildCanonicalUrl(siteName, pathname) }),
985
- hrefLangs.map(({ href, hrefLang }, index2) => /* @__PURE__ */ jsxRuntime.jsx("link", { rel: "alternate", hrefLang, href: index$7.buildCanonicalUrl(siteName, href) }, index2)),
1024
+ /* @__PURE__ */ jsxRuntime.jsx("title", { children: pageTitle }),
1025
+ /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "description", content: pageDescription }),
1026
+ /* @__PURE__ */ jsxRuntime.jsx("link", { rel: "canonical", href: canonicalUrl ?? pageUrl }),
1027
+ /* @__PURE__ */ jsxRuntime.jsx(HrefLangs, { siteName, hrefLangs }),
1028
+ /* @__PURE__ */ jsxRuntime.jsx(JsonLd, { schemas: { organization: organizationSchema, website: websiteSchema, webpage: webpageSchema } }),
986
1029
  children
987
1030
  ] });
988
1031
  };
@@ -1264,13 +1307,8 @@ const StrapiComponent = ({ type, props, imageComponent }) => {
1264
1307
  return null;
1265
1308
  }
1266
1309
  };
1267
- function isStrapiContent(array) {
1268
- return Array.isArray(array) && array.every(
1269
- (item) => typeof item === "object" && item !== null && "__typename" in item && typeof item.__typename === "string"
1270
- );
1271
- }
1272
1310
  const StrapiContentRenderer = ({ content, imageComponent }) => {
1273
- if (!isStrapiContent(content)) {
1311
+ if (!index$5.isStrapiContent(content)) {
1274
1312
  return null;
1275
1313
  }
1276
1314
  return content.map(({ __typename: type, ...props }, index2) => /* @__PURE__ */ jsxRuntime.jsx(StrapiComponent, { type, props, imageComponent }, index2));
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ const index = require("./index-CAjUjAgI.js");
3
+ const index$1 = require("./index-BU1gLt1p.js");
4
+ const DUMMY_PAGE_TYPE = "DUMMY";
5
+ const NavigationSlug = {
6
+ HEADER: "header-navigation",
7
+ FOOTER: "footer-navigation"
8
+ };
9
+ function isValidPath(value) {
10
+ return typeof value === "string" && (value === "" || index.isRelativePath(value));
11
+ }
12
+ function isValidType(value) {
13
+ return typeof value === "string" && value.toUpperCase() !== DUMMY_PAGE_TYPE;
14
+ }
15
+ function isValidTitle(value) {
16
+ return typeof value === "string" && value.toUpperCase() !== DUMMY_PAGE_TYPE;
17
+ }
18
+ function transformNavItems(items) {
19
+ if (!items || !items.length) {
20
+ return [];
21
+ }
22
+ const transformed = [];
23
+ items.forEach((item) => {
24
+ var _a;
25
+ if (item && isValidTitle(item.title) && isValidType(item.type) && isValidPath(item.path)) {
26
+ const isNavGroup = (_a = item.items) == null ? void 0 : _a.length;
27
+ transformed.push({
28
+ label: item.title,
29
+ slug: isNavGroup ? "" : item.path.slice(1),
30
+ ...isNavGroup && { children: transformNavItems(item.items) }
31
+ });
32
+ }
33
+ });
34
+ return transformed;
35
+ }
36
+ function transformSiteNavigation(strapiNavigation) {
37
+ const siteNavigation = {
38
+ header: {},
39
+ footer: {}
40
+ };
41
+ if (!strapiNavigation) {
42
+ return siteNavigation;
43
+ }
44
+ const groups = strapiNavigation.items;
45
+ for (const group of groups ?? []) {
46
+ const { slug, locale, items } = group ?? {};
47
+ if (locale && slug === NavigationSlug.HEADER) {
48
+ siteNavigation.header[locale] = transformNavItems(items ?? []);
49
+ }
50
+ if (locale && slug === NavigationSlug.FOOTER) {
51
+ siteNavigation.footer[locale] = transformNavItems(items ?? []);
52
+ }
53
+ }
54
+ return siteNavigation;
55
+ }
56
+ function getNavigation(fallback, strapiNavigation) {
57
+ const siteNavigation = {
58
+ header: fallback.header,
59
+ footer: fallback.footer
60
+ };
61
+ if (!strapiNavigation) {
62
+ return siteNavigation;
63
+ }
64
+ const navigation = transformSiteNavigation(strapiNavigation);
65
+ siteNavigation.header = { ...siteNavigation.header, ...navigation.header };
66
+ siteNavigation.footer = { ...siteNavigation.footer, ...navigation.footer };
67
+ return siteNavigation;
68
+ }
69
+ function extractAuthor(author) {
70
+ if (author == null ? void 0 : author.name) {
71
+ return { name: author.name };
72
+ }
73
+ return null;
74
+ }
75
+ function extractGame(content) {
76
+ var _a, _b;
77
+ if (content) {
78
+ const gameInfo = content.find(
79
+ (component) => (component == null ? void 0 : component.__typename) === "STRAPI__COMPONENT_CONTENT_GAME_INFO"
80
+ );
81
+ const gameDemo = content.find(
82
+ (component) => (component == null ? void 0 : component.__typename) === "STRAPI__COMPONENT_CONTENT_GAME_DEMO"
83
+ );
84
+ const name = (gameDemo == null ? void 0 : gameDemo.name) ?? ((_a = gameInfo == null ? void 0 : gameInfo.general) == null ? void 0 : _a.NAME);
85
+ const genre = (_b = gameInfo == null ? void 0 : gameInfo.general) == null ? void 0 : _b.TYPE;
86
+ if (name) {
87
+ return {
88
+ name,
89
+ ...genre ? { genre } : {}
90
+ };
91
+ }
92
+ }
93
+ return null;
94
+ }
95
+ function parseReviewHeading(content) {
96
+ const firstComponent = content ? content[0] : null;
97
+ const firstRichText = firstComponent && (firstComponent == null ? void 0 : firstComponent.__typename) === "STRAPI__COMPONENT_CONTENT_RICH_TEXT" ? firstComponent.content.data.content : null;
98
+ if (firstRichText) {
99
+ const [title, description] = firstRichText.split("\n");
100
+ if (title.startsWith("#")) {
101
+ return { title: title.slice(1).trim(), description: description.trim() };
102
+ }
103
+ }
104
+ return null;
105
+ }
106
+ function extractReview(content, seo, createdAt, updatedAt) {
107
+ if (content) {
108
+ const articleInfo = content.find(
109
+ (component) => (component == null ? void 0 : component.__typename) === "STRAPI__COMPONENT_CONTENT_ARTICLE_INFO"
110
+ );
111
+ const maybeHeading = parseReviewHeading(content);
112
+ const title = (articleInfo == null ? void 0 : articleInfo.title) || (maybeHeading == null ? void 0 : maybeHeading.title) || (seo == null ? void 0 : seo.metaTitle);
113
+ const description = (articleInfo == null ? void 0 : articleInfo.description) || (maybeHeading == null ? void 0 : maybeHeading.description) || (seo == null ? void 0 : seo.metaDescription);
114
+ if (title && description && createdAt)
115
+ return {
116
+ title,
117
+ description,
118
+ publishedAt: createdAt,
119
+ updatedAt: updatedAt || createdAt
120
+ };
121
+ }
122
+ return null;
123
+ }
124
+ function extractSeoData(pageData, pageContext) {
125
+ const result = {
126
+ locale: null,
127
+ meta: { title: null, description: null },
128
+ canonicalUrl: null,
129
+ hrefLangs: [],
130
+ structuredData: null
131
+ };
132
+ if (index$1.isStrapiPageContext(pageContext)) {
133
+ result.hrefLangs = pageContext.hrefLangs ?? [];
134
+ }
135
+ if (index$1.isStrapiPageData(pageData)) {
136
+ const { locale, seo, canonicalUrl, author, content, createdAt, updatedAt } = pageData ?? {};
137
+ const { metaTitle, metaDescription } = seo ?? {};
138
+ result.locale = locale ?? null;
139
+ result.canonicalUrl = canonicalUrl ?? null;
140
+ result.meta = { title: metaTitle ?? null, description: metaDescription ?? null };
141
+ const structuredDataContent = {};
142
+ if (index$1.isStrapiContent(content)) {
143
+ const review = extractReview(content, seo ?? null, createdAt ?? null, updatedAt ?? null);
144
+ const game = extractGame(content);
145
+ if (review && game) {
146
+ structuredDataContent.review = review;
147
+ structuredDataContent.game = game;
148
+ const reviewAuthor = extractAuthor(author ?? null);
149
+ if (reviewAuthor) {
150
+ structuredDataContent.author = reviewAuthor;
151
+ }
152
+ }
153
+ }
154
+ result.structuredData = structuredDataContent ? {
155
+ format: "json-ld",
156
+ entity: "game-review",
157
+ content: structuredDataContent
158
+ } : null;
159
+ }
160
+ return result;
161
+ }
162
+ function getSiteName(url) {
163
+ if (!url) {
164
+ return "";
165
+ }
166
+ return url.replace(/^https?:\/\//, "");
167
+ }
168
+ function getLocale(defaultLocaleCode, locales) {
169
+ let locale = { code: "en", name: "Default" };
170
+ if (defaultLocaleCode && (locales == null ? void 0 : locales.length)) {
171
+ const foundLocale = locales.find(({ code }) => code === defaultLocaleCode);
172
+ if (foundLocale) {
173
+ locale = foundLocale;
174
+ }
175
+ }
176
+ return locale;
177
+ }
178
+ function getLocales(defaultLocaleCode, locales) {
179
+ if (!locales) {
180
+ return [];
181
+ }
182
+ return [...locales].sort((a, b) => {
183
+ if (a.code === defaultLocaleCode) return -1;
184
+ if (b.code === defaultLocaleCode) return 1;
185
+ return 0;
186
+ });
187
+ }
188
+ exports.extractSeoData = extractSeoData;
189
+ exports.getLocale = getLocale;
190
+ exports.getLocales = getLocales;
191
+ exports.getNavigation = getNavigation;
192
+ exports.getSiteName = getSiteName;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  const jsxRuntime = require("react/jsx-runtime");
3
3
  const react = require("@chakra-ui/react");
4
- const index = require("./index-D-jM-cHx.js");
4
+ const index = require("./index-DZc8PJET.js");
5
5
  require("@mdx-js/react");
6
6
  const reactI18next = require("react-i18next");
7
7
  const index$2 = require("./index-C6MG_f24.js");
@@ -173,9 +173,8 @@ const LinkButton = ({
173
173
  );
174
174
  };
175
175
  const Logo = () => {
176
- const { metadata } = index.useSiteContext();
177
- const { logo } = metadata;
178
- return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { display: "flex", h: { base: 10, md: 14 }, alignSelf: "center", overflow: "hidden", children: /* @__PURE__ */ jsxRuntime.jsx(index.Image, { src: logo, alt: "Logo", objectFit: "contain" }) });
176
+ const { logo } = index.useSiteContext();
177
+ return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { display: "flex", h: { base: 10, md: 14 }, alignSelf: "center", overflow: "hidden", children: /* @__PURE__ */ jsxRuntime.jsx(index.Image, { src: logo.src, alt: logo.alt, objectFit: "contain" }) });
179
178
  };
180
179
  const StarSizeMap = {
181
180
  sm: "1rem",