@anywayseo/tools 6.1.0 → 6.2.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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const index = require("../index-C93pA9Jv.js");
3
+ const index = require("../index-ISfgFSXE.js");
4
4
  const index$1 = require("../index-CxuOu0E2.js");
5
5
  const index$2 = require("../index-DDg_PkD2.js");
6
6
  const index$3 = require("../index-DAPaiozu.js");
@@ -1,4 +1,4 @@
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-BBU_vIrY.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-BtS01kyg.mjs";
2
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-2sU4ya6z.mjs";
3
3
  import { H as H2, a as a3, b as b3, O, P as P2, U } from "../index-BEjKnOZA.mjs";
4
4
  import { I as I2, L as L3 } from "../index-B5WurBlm.mjs";
@@ -1,8 +1,8 @@
1
1
  import { FC } from 'react';
2
- import { IHrefLang } from '../../../types';
2
+ import { ISeo } from '../../../types';
3
3
  type HrefLangsProps = {
4
4
  siteName: string;
5
- hrefLangs: IHrefLang[];
5
+ hrefLangs: ISeo['hrefLangs'];
6
6
  };
7
7
  declare const HrefLangs: FC<HrefLangsProps>;
8
8
  export default HrefLangs;
@@ -1,13 +1,7 @@
1
1
  import { FC, PropsWithChildren } from 'react';
2
- import { SeoCanonical, SeoDescription, SeoHrefLangs, SeoLocale, SeoStructuredData, SeoTitle } from './types';
3
- type SeoProps = PropsWithChildren<{
2
+ import { ISeo } from '../../types';
3
+ type SeoProps = PropsWithChildren<ISeo & {
4
4
  pathname: Location['pathname'];
5
- locale?: SeoLocale;
6
- title?: SeoTitle;
7
- description?: SeoDescription;
8
- canonicalUrl?: SeoCanonical;
9
- hrefLangs?: SeoHrefLangs;
10
- structuredData?: SeoStructuredData;
11
5
  }>;
12
6
  declare const Seo: FC<SeoProps>;
13
7
  export default Seo;
@@ -0,0 +1,8 @@
1
+ import { FC } from 'react';
2
+ import { IOpenGraph, IOpenGraphMetaItem } from '../../../types';
3
+ type OpenGraphProps = {
4
+ meta: IOpenGraphMetaItem[];
5
+ options?: IOpenGraph['options'];
6
+ };
7
+ declare const OpenGraph: FC<OpenGraphProps>;
8
+ export default OpenGraph;
@@ -1,3 +1,3 @@
1
- import { ISeoMetaItemPlaceholders, SeoDescription, SeoTitle } from './types';
1
+ import { ISeoMetaItemPlaceholders, SeoMetaItem } from '../../types';
2
2
  export declare function buildPlaceholders(siteName: string, lang: string): ISeoMetaItemPlaceholders;
3
- export declare function getSeoMetaItem<T extends SeoTitle | SeoDescription>(item: NonNullable<T>, placeholders: ISeoMetaItemPlaceholders): string;
3
+ export declare function getSeoMetaItem<T extends SeoMetaItem>(item: NonNullable<T>, placeholders: ISeoMetaItemPlaceholders): string;
@@ -1,5 +1,5 @@
1
1
  import { i as isRelativePath } from "./index-CQC6DRGf.mjs";
2
- import { c as isStrapiPageContext, b as isStrapiPageData, i as isStrapiContent, a as isStrapiRichText } from "./index-CoNbTY7l.mjs";
2
+ import { c as isStrapiPageContext, b as isStrapiPageData, i as isStrapiContent, a as isStrapiRichText } from "./index-BTfTkIed.mjs";
3
3
  const DUMMY_PAGE_TYPE = "DUMMY";
4
4
  const NavigationSlug = {
5
5
  HEADER: "header-navigation",
@@ -125,33 +125,33 @@ function extractReview(content, seo, createdAt, updatedAt) {
125
125
  }
126
126
  return null;
127
127
  }
128
- function extractSeoData(pageData, pageContext) {
129
- const result = {
130
- locale: null,
131
- meta: { title: null, description: null },
132
- canonicalUrl: null,
133
- hrefLangs: [],
134
- structuredData: null
135
- };
128
+ function buildSeoFromStrapi(pageData, pageContext) {
129
+ const result = {};
136
130
  if (isStrapiPageContext(pageContext)) {
137
- result.hrefLangs = pageContext.hrefLangs ?? [];
131
+ result.hrefLangs = pageContext.hrefLangs;
138
132
  }
139
133
  if (isStrapiPageData(pageData)) {
140
134
  const { locale, seo, canonicalUrl, author, content, createdAt, updatedAt } = pageData ?? {};
141
135
  const { metaTitle, metaDescription } = seo ?? {};
142
- result.locale = locale ?? null;
143
- result.canonicalUrl = canonicalUrl ?? null;
136
+ result.lang = locale;
137
+ result.canonicalUrl = canonicalUrl;
144
138
  result.meta = { title: metaTitle ?? null, description: metaDescription ?? null };
145
139
  const structuredDataContent = {};
140
+ const openGraphContent = {};
146
141
  if (isStrapiContent(content)) {
147
142
  const review = extractReview(content, seo ?? null, createdAt ?? null, updatedAt ?? null);
148
143
  const game = extractGame(content);
149
144
  if (review && game) {
150
145
  structuredDataContent.review = review;
151
146
  structuredDataContent.game = game;
147
+ openGraphContent.article = {
148
+ createdAt: review.publishedAt,
149
+ updatedAt: review.updatedAt || review.publishedAt
150
+ };
152
151
  const reviewAuthor = extractAuthor(author ?? null);
153
152
  if (reviewAuthor) {
154
153
  structuredDataContent.author = reviewAuthor;
154
+ openGraphContent.article.author = reviewAuthor.name;
155
155
  }
156
156
  }
157
157
  }
@@ -160,6 +160,10 @@ function extractSeoData(pageData, pageContext) {
160
160
  entity: "game-review",
161
161
  content: structuredDataContent
162
162
  } : null;
163
+ result.openGraph = openGraphContent ? {
164
+ options: { withTwitterCard: true },
165
+ content: openGraphContent
166
+ } : null;
163
167
  }
164
168
  return result;
165
169
  }
@@ -193,6 +197,6 @@ export {
193
197
  getLocale as a,
194
198
  getLocales as b,
195
199
  getNavigation as c,
196
- extractSeoData as e,
200
+ buildSeoFromStrapi as d,
197
201
  getSiteName as g
198
202
  };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const index = require("./index-CAjUjAgI.js");
3
- const index$1 = require("./index-CnVcCa5O.js");
3
+ const index$1 = require("./index-DHKoOk4o.js");
4
4
  const DUMMY_PAGE_TYPE = "DUMMY";
5
5
  const NavigationSlug = {
6
6
  HEADER: "header-navigation",
@@ -126,33 +126,33 @@ function extractReview(content, seo, createdAt, updatedAt) {
126
126
  }
127
127
  return null;
128
128
  }
129
- function extractSeoData(pageData, pageContext) {
130
- const result = {
131
- locale: null,
132
- meta: { title: null, description: null },
133
- canonicalUrl: null,
134
- hrefLangs: [],
135
- structuredData: null
136
- };
129
+ function buildSeoFromStrapi(pageData, pageContext) {
130
+ const result = {};
137
131
  if (index$1.isStrapiPageContext(pageContext)) {
138
- result.hrefLangs = pageContext.hrefLangs ?? [];
132
+ result.hrefLangs = pageContext.hrefLangs;
139
133
  }
140
134
  if (index$1.isStrapiPageData(pageData)) {
141
135
  const { locale, seo, canonicalUrl, author, content, createdAt, updatedAt } = pageData ?? {};
142
136
  const { metaTitle, metaDescription } = seo ?? {};
143
- result.locale = locale ?? null;
144
- result.canonicalUrl = canonicalUrl ?? null;
137
+ result.lang = locale;
138
+ result.canonicalUrl = canonicalUrl;
145
139
  result.meta = { title: metaTitle ?? null, description: metaDescription ?? null };
146
140
  const structuredDataContent = {};
141
+ const openGraphContent = {};
147
142
  if (index$1.isStrapiContent(content)) {
148
143
  const review = extractReview(content, seo ?? null, createdAt ?? null, updatedAt ?? null);
149
144
  const game = extractGame(content);
150
145
  if (review && game) {
151
146
  structuredDataContent.review = review;
152
147
  structuredDataContent.game = game;
148
+ openGraphContent.article = {
149
+ createdAt: review.publishedAt,
150
+ updatedAt: review.updatedAt || review.publishedAt
151
+ };
153
152
  const reviewAuthor = extractAuthor(author ?? null);
154
153
  if (reviewAuthor) {
155
154
  structuredDataContent.author = reviewAuthor;
155
+ openGraphContent.article.author = reviewAuthor.name;
156
156
  }
157
157
  }
158
158
  }
@@ -161,6 +161,10 @@ function extractSeoData(pageData, pageContext) {
161
161
  entity: "game-review",
162
162
  content: structuredDataContent
163
163
  } : null;
164
+ result.openGraph = openGraphContent ? {
165
+ options: { withTwitterCard: true },
166
+ content: openGraphContent
167
+ } : null;
164
168
  }
165
169
  return result;
166
170
  }
@@ -190,7 +194,7 @@ function getLocales(defaultLocaleCode, locales) {
190
194
  return 0;
191
195
  });
192
196
  }
193
- exports.extractSeoData = extractSeoData;
197
+ exports.buildSeoFromStrapi = buildSeoFromStrapi;
194
198
  exports.getLocale = getLocale;
195
199
  exports.getLocales = getLocales;
196
200
  exports.getNavigation = getNavigation;
@@ -124,6 +124,53 @@ function buildGameReviewSchema(params) {
124
124
  }
125
125
  };
126
126
  }
127
+ function buildOpenGraphMeta(params) {
128
+ const { site, page, lang, content } = params;
129
+ const { article, image } = content ?? {};
130
+ const type = article ? "article" : "website";
131
+ const meta = [
132
+ { property: "og:site_name", content: site.name },
133
+ { property: "og:locale", content: lang },
134
+ { property: "og:type", content: type },
135
+ { property: "og:url", content: page.url },
136
+ { property: "og:title", content: page.title },
137
+ { property: "og:description", content: page.description }
138
+ ];
139
+ if (image) {
140
+ const imageMeta = [
141
+ { property: "og:image", content: image.url },
142
+ { property: "og:image:alt", content: image.alt }
143
+ ];
144
+ if (image.width && image.height) {
145
+ imageMeta.push(
146
+ { property: "og:image:width", content: String(image.width) },
147
+ { property: "og:image:height", content: String(image.height) }
148
+ );
149
+ }
150
+ meta.push(...imageMeta);
151
+ }
152
+ if (article) {
153
+ const articleMeta = [
154
+ { property: "og:article:published_time", content: article.createdAt },
155
+ { property: "og:article:modified_time", content: article.updatedAt }
156
+ ];
157
+ if (article.author) {
158
+ articleMeta.push({ property: "og:article:author", content: article.author });
159
+ }
160
+ if (article.section) {
161
+ articleMeta.push({ property: "og:article:section", content: article.section });
162
+ }
163
+ if (article.tags && article.tags.length) {
164
+ const articleTags = article.tags.map((tag) => ({
165
+ property: "og:article:tag",
166
+ content: tag
167
+ }));
168
+ articleMeta.push(...articleTags);
169
+ }
170
+ meta.push(...articleMeta);
171
+ }
172
+ return meta;
173
+ }
127
174
  function randomComparator() {
128
175
  return Math.random() - 0.5;
129
176
  }
@@ -147,6 +194,7 @@ export {
147
194
  isStrapiContent as i,
148
195
  buildWebpageSchema as j,
149
196
  buildGameReviewSchema as k,
150
- getSeededRandomComparator as l,
197
+ buildOpenGraphMeta as l,
198
+ getSeededRandomComparator as m,
151
199
  randomComparator as r
152
200
  };
@@ -11,7 +11,7 @@ import { useRef, useState, useLayoutEffect, Fragment as Fragment$1, useMemo } fr
11
11
  import { d as SocialNetworks, L as LinkButton, R as Rating } from "./index-2sU4ya6z.mjs";
12
12
  import { a as Heading2, H as Heading1, P as Paragraph, U as Unordered, O as Ordered } from "./index-BEjKnOZA.mjs";
13
13
  import { a as buildCanonicalUrl } from "./index-CQC6DRGf.mjs";
14
- import { l as getSeededRandomComparator, r as randomComparator, g as getCurrencySymbol, d as buildGraph, e as buildOrganizationSchema, f as buildWebsiteSchema, h as getEntitySchema, j as buildWebpageSchema, i as isStrapiContent } from "./index-CoNbTY7l.mjs";
14
+ import { m as getSeededRandomComparator, r as randomComparator, g as getCurrencySymbol, d as buildGraph, e as buildOrganizationSchema, f as buildWebsiteSchema, h as getEntitySchema, j as buildWebpageSchema, l as buildOpenGraphMeta, i as isStrapiContent } from "./index-BTfTkIed.mjs";
15
15
  import { f as formatDate, b as formatNumber, a as getCurrentMonth, g as getCurrentYear } from "./index-BPthShL-.mjs";
16
16
  import { u as usePrimaryColors } from "./index-BS5T9Il4.mjs";
17
17
  import { t } from "i18next";
@@ -950,26 +950,12 @@ const ProsCons = ({ items, ...boxProps }) => {
950
950
  /* @__PURE__ */ jsx(ProsConsCard, { itemType: "cons", items: cons })
951
951
  ] });
952
952
  };
953
- function buildPlaceholders(siteName, lang) {
954
- return {
955
- siteName,
956
- currentYear: getCurrentYear(lang),
957
- currentMonth: getCurrentMonth(lang)
958
- };
959
- }
960
- function replacePlaceholders(text, placeholders) {
961
- Object.entries(placeholders).forEach(([placeholder, replacement]) => {
962
- const regex = new RegExp(`{{${placeholder}}}`, "g");
963
- text = text.replace(regex, replacement);
964
- });
965
- return text;
966
- }
967
- function getSeoMetaItem(item, placeholders) {
968
- if (typeof item === "string") {
969
- return replacePlaceholders(item, placeholders);
953
+ const HrefLangs = ({ siteName, hrefLangs }) => {
954
+ if (!(hrefLangs == null ? void 0 : hrefLangs.length)) {
955
+ return null;
970
956
  }
971
- return item(placeholders);
972
- }
957
+ return hrefLangs.map(({ href, hrefLang }, index) => /* @__PURE__ */ jsx("link", { rel: "alternate", hrefLang, href: buildCanonicalUrl(siteName, href) }, index));
958
+ };
973
959
  const JsonLd = ({ schemas }) => {
974
960
  const graph = buildGraph(schemas);
975
961
  if (!graph.length) {
@@ -989,18 +975,42 @@ const JsonLd = ({ schemas }) => {
989
975
  }
990
976
  );
991
977
  };
992
- const HrefLangs = ({ siteName, hrefLangs }) => {
993
- return hrefLangs.map(({ href, hrefLang }, index) => /* @__PURE__ */ jsx("link", { rel: "alternate", hrefLang, href: buildCanonicalUrl(siteName, href) }, index));
978
+ const OpenGraph = ({ meta, options }) => {
979
+ const { withTwitterCard = true } = options ?? {};
980
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
981
+ meta.map(({ property, content }, index) => /* @__PURE__ */ jsx("meta", { property, content }, index)),
982
+ withTwitterCard && /* @__PURE__ */ jsx("meta", { name: "twitter:card", content: "summary_large_image" })
983
+ ] });
994
984
  };
985
+ function buildPlaceholders(siteName, lang) {
986
+ return {
987
+ siteName,
988
+ currentYear: getCurrentYear(lang),
989
+ currentMonth: getCurrentMonth(lang)
990
+ };
991
+ }
992
+ function replacePlaceholders(text, placeholders) {
993
+ Object.entries(placeholders).forEach(([placeholder, replacement]) => {
994
+ const regex = new RegExp(`{{${placeholder}}}`, "g");
995
+ text = text.replace(regex, replacement);
996
+ });
997
+ return text.trim();
998
+ }
999
+ function getSeoMetaItem(item, placeholders) {
1000
+ if (typeof item === "string") {
1001
+ return replacePlaceholders(item, placeholders);
1002
+ }
1003
+ return item(placeholders);
1004
+ }
995
1005
  const Seo = ({
996
1006
  children,
997
1007
  pathname,
998
- locale,
999
- title,
1000
- description,
1008
+ lang: locale,
1009
+ meta,
1001
1010
  canonicalUrl,
1002
- hrefLangs = [],
1003
- structuredData
1011
+ hrefLangs,
1012
+ structuredData,
1013
+ openGraph
1004
1014
  }) => {
1005
1015
  const { metadata: siteMetadata, logo: siteLogo, localization } = useSiteContext();
1006
1016
  const { name: siteName, seo: siteSeo } = siteMetadata;
@@ -1010,14 +1020,15 @@ const Seo = ({
1010
1020
  const placeholders = buildPlaceholders(siteName, lang);
1011
1021
  const siteUrl = buildCanonicalUrl(siteName);
1012
1022
  const pageUrl = buildCanonicalUrl(siteName, pathname);
1013
- const pageTitle = getSeoMetaItem(title ?? defaultTitle, placeholders);
1014
- const pageDescription = getSeoMetaItem(description ?? defaultDescription, placeholders);
1023
+ const pageTitle = getSeoMetaItem((meta == null ? void 0 : meta.title) ?? defaultTitle, placeholders);
1024
+ const pageDescription = getSeoMetaItem((meta == null ? void 0 : meta.description) ?? defaultDescription, placeholders);
1015
1025
  const siteData = { url: siteUrl, name: siteName, logo: siteLogo };
1016
1026
  const pageData = { url: pageUrl, title: pageTitle, description: pageDescription };
1017
1027
  const organizationSchema = buildOrganizationSchema({ site: siteData, lang });
1018
1028
  const websiteSchema = buildWebsiteSchema({ site: siteData, lang });
1019
1029
  const entitySchema = getEntitySchema({ site: siteData, page: pageData, structuredData });
1020
1030
  const webpageSchema = buildWebpageSchema({ site: siteData, page: pageData, lang }, entitySchema);
1031
+ const openGraphMeta = buildOpenGraphMeta({ site: siteData, page: pageData, content: openGraph == null ? void 0 : openGraph.content, lang });
1021
1032
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1022
1033
  /* @__PURE__ */ jsx("html", { lang }),
1023
1034
  /* @__PURE__ */ jsx("title", { children: pageTitle }),
@@ -1025,6 +1036,7 @@ const Seo = ({
1025
1036
  /* @__PURE__ */ jsx("link", { rel: "canonical", href: canonicalUrl ?? pageUrl }),
1026
1037
  /* @__PURE__ */ jsx(HrefLangs, { siteName, hrefLangs }),
1027
1038
  /* @__PURE__ */ jsx(JsonLd, { schemas: { organization: organizationSchema, website: websiteSchema, webpage: webpageSchema } }),
1039
+ /* @__PURE__ */ jsx(OpenGraph, { meta: openGraphMeta, options: openGraph == null ? void 0 : openGraph.options }),
1028
1040
  children
1029
1041
  ] });
1030
1042
  };
@@ -125,6 +125,53 @@ function buildGameReviewSchema(params) {
125
125
  }
126
126
  };
127
127
  }
128
+ function buildOpenGraphMeta(params) {
129
+ const { site, page, lang, content } = params;
130
+ const { article, image } = content ?? {};
131
+ const type = article ? "article" : "website";
132
+ const meta = [
133
+ { property: "og:site_name", content: site.name },
134
+ { property: "og:locale", content: lang },
135
+ { property: "og:type", content: type },
136
+ { property: "og:url", content: page.url },
137
+ { property: "og:title", content: page.title },
138
+ { property: "og:description", content: page.description }
139
+ ];
140
+ if (image) {
141
+ const imageMeta = [
142
+ { property: "og:image", content: image.url },
143
+ { property: "og:image:alt", content: image.alt }
144
+ ];
145
+ if (image.width && image.height) {
146
+ imageMeta.push(
147
+ { property: "og:image:width", content: String(image.width) },
148
+ { property: "og:image:height", content: String(image.height) }
149
+ );
150
+ }
151
+ meta.push(...imageMeta);
152
+ }
153
+ if (article) {
154
+ const articleMeta = [
155
+ { property: "og:article:published_time", content: article.createdAt },
156
+ { property: "og:article:modified_time", content: article.updatedAt }
157
+ ];
158
+ if (article.author) {
159
+ articleMeta.push({ property: "og:article:author", content: article.author });
160
+ }
161
+ if (article.section) {
162
+ articleMeta.push({ property: "og:article:section", content: article.section });
163
+ }
164
+ if (article.tags && article.tags.length) {
165
+ const articleTags = article.tags.map((tag) => ({
166
+ property: "og:article:tag",
167
+ content: tag
168
+ }));
169
+ articleMeta.push(...articleTags);
170
+ }
171
+ meta.push(...articleMeta);
172
+ }
173
+ return meta;
174
+ }
128
175
  function randomComparator() {
129
176
  return Math.random() - 0.5;
130
177
  }
@@ -138,6 +185,7 @@ function getSeededRandomComparator(seed) {
138
185
  }
139
186
  exports.buildGameReviewSchema = buildGameReviewSchema;
140
187
  exports.buildGraph = buildGraph;
188
+ exports.buildOpenGraphMeta = buildOpenGraphMeta;
141
189
  exports.buildOrganizationSchema = buildOrganizationSchema;
142
190
  exports.buildWebpageSchema = buildWebpageSchema;
143
191
  exports.buildWebsiteSchema = buildWebsiteSchema;
@@ -12,7 +12,7 @@ const react$1 = require("react");
12
12
  const index$2 = require("./index-CxuOu0E2.js");
13
13
  const index$3 = require("./index-DDg_PkD2.js");
14
14
  const index$7 = require("./index-CAjUjAgI.js");
15
- const index$5 = require("./index-CnVcCa5O.js");
15
+ const index$5 = require("./index-DHKoOk4o.js");
16
16
  const index$1 = require("./index-ov4J7p3D.js");
17
17
  const index$4 = require("./index-CuIVcnIS.js");
18
18
  const i18next = require("i18next");
@@ -951,26 +951,12 @@ 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
- }
961
- function replacePlaceholders(text, placeholders) {
962
- Object.entries(placeholders).forEach(([placeholder, replacement]) => {
963
- const regex = new RegExp(`{{${placeholder}}}`, "g");
964
- text = text.replace(regex, replacement);
965
- });
966
- return text;
967
- }
968
- function getSeoMetaItem(item, placeholders) {
969
- if (typeof item === "string") {
970
- return replacePlaceholders(item, placeholders);
954
+ const HrefLangs = ({ siteName, hrefLangs }) => {
955
+ if (!(hrefLangs == null ? void 0 : hrefLangs.length)) {
956
+ return null;
971
957
  }
972
- return item(placeholders);
973
- }
958
+ return hrefLangs.map(({ href, hrefLang }, index2) => /* @__PURE__ */ jsxRuntime.jsx("link", { rel: "alternate", hrefLang, href: index$7.buildCanonicalUrl(siteName, href) }, index2));
959
+ };
974
960
  const JsonLd = ({ schemas }) => {
975
961
  const graph = index$5.buildGraph(schemas);
976
962
  if (!graph.length) {
@@ -990,18 +976,42 @@ const JsonLd = ({ schemas }) => {
990
976
  }
991
977
  );
992
978
  };
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));
979
+ const OpenGraph = ({ meta, options }) => {
980
+ const { withTwitterCard = true } = options ?? {};
981
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
982
+ meta.map(({ property, content }, index2) => /* @__PURE__ */ jsxRuntime.jsx("meta", { property, content }, index2)),
983
+ withTwitterCard && /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:card", content: "summary_large_image" })
984
+ ] });
995
985
  };
986
+ function buildPlaceholders(siteName, lang) {
987
+ return {
988
+ siteName,
989
+ currentYear: index$1.getCurrentYear(lang),
990
+ currentMonth: index$1.getCurrentMonth(lang)
991
+ };
992
+ }
993
+ function replacePlaceholders(text, placeholders) {
994
+ Object.entries(placeholders).forEach(([placeholder, replacement]) => {
995
+ const regex = new RegExp(`{{${placeholder}}}`, "g");
996
+ text = text.replace(regex, replacement);
997
+ });
998
+ return text.trim();
999
+ }
1000
+ function getSeoMetaItem(item, placeholders) {
1001
+ if (typeof item === "string") {
1002
+ return replacePlaceholders(item, placeholders);
1003
+ }
1004
+ return item(placeholders);
1005
+ }
996
1006
  const Seo = ({
997
1007
  children,
998
1008
  pathname,
999
- locale,
1000
- title,
1001
- description,
1009
+ lang: locale,
1010
+ meta,
1002
1011
  canonicalUrl,
1003
- hrefLangs = [],
1004
- structuredData
1012
+ hrefLangs,
1013
+ structuredData,
1014
+ openGraph
1005
1015
  }) => {
1006
1016
  const { metadata: siteMetadata, logo: siteLogo, localization } = index.useSiteContext();
1007
1017
  const { name: siteName, seo: siteSeo } = siteMetadata;
@@ -1011,14 +1021,15 @@ const Seo = ({
1011
1021
  const placeholders = buildPlaceholders(siteName, lang);
1012
1022
  const siteUrl = index$7.buildCanonicalUrl(siteName);
1013
1023
  const pageUrl = index$7.buildCanonicalUrl(siteName, pathname);
1014
- const pageTitle = getSeoMetaItem(title ?? defaultTitle, placeholders);
1015
- const pageDescription = getSeoMetaItem(description ?? defaultDescription, placeholders);
1024
+ const pageTitle = getSeoMetaItem((meta == null ? void 0 : meta.title) ?? defaultTitle, placeholders);
1025
+ const pageDescription = getSeoMetaItem((meta == null ? void 0 : meta.description) ?? defaultDescription, placeholders);
1016
1026
  const siteData = { url: siteUrl, name: siteName, logo: siteLogo };
1017
1027
  const pageData = { url: pageUrl, title: pageTitle, description: pageDescription };
1018
1028
  const organizationSchema = index$5.buildOrganizationSchema({ site: siteData, lang });
1019
1029
  const websiteSchema = index$5.buildWebsiteSchema({ site: siteData, lang });
1020
1030
  const entitySchema = index$5.getEntitySchema({ site: siteData, page: pageData, structuredData });
1021
1031
  const webpageSchema = index$5.buildWebpageSchema({ site: siteData, page: pageData, lang }, entitySchema);
1032
+ const openGraphMeta = index$5.buildOpenGraphMeta({ site: siteData, page: pageData, content: openGraph == null ? void 0 : openGraph.content, lang });
1022
1033
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1023
1034
  /* @__PURE__ */ jsxRuntime.jsx("html", { lang }),
1024
1035
  /* @__PURE__ */ jsxRuntime.jsx("title", { children: pageTitle }),
@@ -1026,6 +1037,7 @@ const Seo = ({
1026
1037
  /* @__PURE__ */ jsxRuntime.jsx("link", { rel: "canonical", href: canonicalUrl ?? pageUrl }),
1027
1038
  /* @__PURE__ */ jsxRuntime.jsx(HrefLangs, { siteName, hrefLangs }),
1028
1039
  /* @__PURE__ */ jsxRuntime.jsx(JsonLd, { schemas: { organization: organizationSchema, website: websiteSchema, webpage: webpageSchema } }),
1040
+ /* @__PURE__ */ jsxRuntime.jsx(OpenGraph, { meta: openGraphMeta, options: openGraph == null ? void 0 : openGraph.options }),
1029
1041
  children
1030
1042
  ] });
1031
1043
  };
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const index = require("./index-C93pA9Jv.js");
3
+ const index = require("./index-ISfgFSXE.js");
4
4
  const index$1 = require("./index-CxuOu0E2.js");
5
5
  const index$2 = require("./index-DDg_PkD2.js");
6
6
  const index$3 = require("./index-DAPaiozu.js");
@@ -11,8 +11,8 @@ const layout = require("./layout/index.cjs");
11
11
  const index$6 = require("./index-BAxlqkw0.js");
12
12
  const index$7 = require("./index-CMLDQbgR.js");
13
13
  const index$8 = require("./index-C6MG_f24.js");
14
- const index$9 = require("./index-P_fDAJVz.js");
15
- const index$a = require("./index-CnVcCa5O.js");
14
+ const index$9 = require("./index-BKWX6mIo.js");
15
+ const index$a = require("./index-DHKoOk4o.js");
16
16
  const index$b = require("./index-ov4J7p3D.js");
17
17
  const index$c = require("./index-CAjUjAgI.js");
18
18
  const index$d = require("./index-CbuiYkSg.js");
@@ -80,13 +80,14 @@ exports.GameCharacteristic = index$7.GameCharacteristic;
80
80
  exports.GameVolatility = index$7.GameVolatility;
81
81
  exports.InformerType = index$7.InformerType;
82
82
  exports.Animation = index$8.Animation;
83
- exports.extractSeoData = index$9.extractSeoData;
83
+ exports.buildSeoFromStrapi = index$9.buildSeoFromStrapi;
84
84
  exports.getLocale = index$9.getLocale;
85
85
  exports.getLocales = index$9.getLocales;
86
86
  exports.getNavigation = index$9.getNavigation;
87
87
  exports.getSiteName = index$9.getSiteName;
88
88
  exports.buildGameReviewSchema = index$a.buildGameReviewSchema;
89
89
  exports.buildGraph = index$a.buildGraph;
90
+ exports.buildOpenGraphMeta = index$a.buildOpenGraphMeta;
90
91
  exports.buildOrganizationSchema = index$a.buildOrganizationSchema;
91
92
  exports.buildWebpageSchema = index$a.buildWebpageSchema;
92
93
  exports.buildWebsiteSchema = index$a.buildWebsiteSchema;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
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-BBU_vIrY.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-BtS01kyg.mjs";
2
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-2sU4ya6z.mjs";
3
3
  import { H as H2, a as a3, b as b3, O, P as P2, U } from "./index-BEjKnOZA.mjs";
4
4
  import { I as I2, L as L3, P as P3, S as S3, u, a as a4 } from "./index-B5WurBlm.mjs";
@@ -9,8 +9,8 @@ import { default as default2 } from "./layout/index.mjs";
9
9
  import { M } from "./index-TcBorTSf.mjs";
10
10
  import { a as a5, C as C3, b as b4, G as G2, I as I3 } from "./index-C6A-3gBz.mjs";
11
11
  import { A as A2 } from "./index-BJRvnR8Q.mjs";
12
- import { e as e2, a as a6, b as b5, c as c3, g as g2 } from "./index-MnQnVvsM.mjs";
13
- import { k as k2, d as d3, e as e3, j as j2, f as f2, g as g3, h as h2, l as l2, i as i2, c as c4, b as b6, a as a7, r as r2 } from "./index-CoNbTY7l.mjs";
12
+ import { d as d3, a as a6, b as b5, c as c3, g as g2 } from "./index-B--qmL1V.mjs";
13
+ import { k as k2, d as d4, l as l2, e as e2, j as j2, f as f2, g as g3, h as h2, m as m2, i as i2, c as c4, b as b6, a as a7, r as r2 } from "./index-BTfTkIed.mjs";
14
14
  import { f as f3, b as b7, a as a8, g as g4, r as r3, t as t2 } from "./index-BPthShL-.mjs";
15
15
  import { a as a9, b as b8, c as c5, i as i3 } from "./index-CQC6DRGf.mjs";
16
16
  import { D, L as L4 } from "./index-BRVKhbs6.mjs";
@@ -78,12 +78,13 @@ export {
78
78
  U as UL,
79
79
  a9 as buildCanonicalUrl,
80
80
  k2 as buildGameReviewSchema,
81
- d3 as buildGraph,
82
- e3 as buildOrganizationSchema,
81
+ d4 as buildGraph,
82
+ l2 as buildOpenGraphMeta,
83
+ e2 as buildOrganizationSchema,
83
84
  b8 as buildPath,
85
+ d3 as buildSeoFromStrapi,
84
86
  j2 as buildWebpageSchema,
85
87
  f2 as buildWebsiteSchema,
86
- e2 as extractSeoData,
87
88
  f3 as formatDate,
88
89
  b7 as formatNumber,
89
90
  g3 as getCurrencySymbol,
@@ -93,7 +94,7 @@ export {
93
94
  a6 as getLocale,
94
95
  b5 as getLocales,
95
96
  c3 as getNavigation,
96
- l2 as getSeededRandomComparator,
97
+ m2 as getSeededRandomComparator,
97
98
  g2 as getSiteName,
98
99
  c5 as isAbsolutePath,
99
100
  i3 as isRelativePath,
@@ -1,11 +1,29 @@
1
- export interface ISeoMetadata {
2
- title: string;
3
- description: string;
1
+ import { Nullable } from '../../common';
2
+ import { ILocale } from '../../i18n';
3
+ /** Meta */
4
+ export interface ISeoMetaItemPlaceholders {
5
+ siteName: string;
6
+ currentYear: string;
7
+ currentMonth: string;
8
+ }
9
+ type SeoMetaItemGetter = (placeholders: ISeoMetaItemPlaceholders) => string;
10
+ export type SeoMetaItem = string | SeoMetaItemGetter;
11
+ export interface ISeoMetadata<T = string> {
12
+ title: T;
13
+ description: T;
4
14
  }
15
+ /** Href Langs */
5
16
  export interface IHrefLang {
6
17
  href: string;
7
18
  hrefLang: string;
8
19
  }
20
+ /** Structured Data */
21
+ interface IStructuredDataImage {
22
+ url: string;
23
+ alt?: string;
24
+ width?: number;
25
+ height?: number;
26
+ }
9
27
  interface IStructuredDataAuthor {
10
28
  name: string;
11
29
  url?: string;
@@ -21,10 +39,12 @@ interface IStructuredDataReview {
21
39
  publishedAt: string;
22
40
  updatedAt?: string;
23
41
  rating?: IStructuredDataRating;
42
+ image?: IStructuredDataImage;
24
43
  }
25
44
  interface IStructuredDataGame {
26
45
  name: string;
27
46
  genre?: string;
47
+ image?: IStructuredDataImage;
28
48
  }
29
49
  export interface IStructuredDataContent {
30
50
  author?: IStructuredDataAuthor;
@@ -38,4 +58,37 @@ export interface IStructuredData {
38
58
  entity: StructuredDataEntity;
39
59
  content: IStructuredDataContent;
40
60
  }
61
+ /** Open Graph */
62
+ interface IOpenGraphImageData {
63
+ url: string;
64
+ alt: string;
65
+ width?: number;
66
+ height?: number;
67
+ }
68
+ interface IOpenGraphArticleData {
69
+ createdAt: string;
70
+ updatedAt: string;
71
+ author?: string;
72
+ section?: string;
73
+ tags?: string[];
74
+ }
75
+ interface IOpenGraphContent {
76
+ image?: IOpenGraphImageData;
77
+ article?: IOpenGraphArticleData;
78
+ }
79
+ interface IOpenGraphOptions {
80
+ withTwitterCard?: boolean;
81
+ }
82
+ export interface IOpenGraph {
83
+ content: IOpenGraphContent;
84
+ options?: IOpenGraphOptions;
85
+ }
86
+ export interface ISeo {
87
+ lang?: Nullable<ILocale['code']>;
88
+ meta?: Nullable<ISeoMetadata<Nullable<SeoMetaItem>>>;
89
+ canonicalUrl?: Nullable<string>;
90
+ hrefLangs?: Nullable<IHrefLang[]>;
91
+ structuredData?: Nullable<IStructuredData>;
92
+ openGraph?: Nullable<IOpenGraph>;
93
+ }
41
94
  export {};
@@ -3,6 +3,6 @@ export * from './common';
3
3
  export * from './components';
4
4
  export * from './content';
5
5
  export * from './i18n';
6
- export * from './json-ld';
6
+ export * from './seo';
7
7
  export * from './site';
8
8
  export * from './theme';
@@ -0,0 +1,2 @@
1
+ export * from './json-ld';
2
+ export * from './open-graph';
@@ -0,0 +1,11 @@
1
+ type OpenGraphImageMetaTag = 'image' | 'image:alt' | 'image:width' | 'image:height';
2
+ type OpenGraphArticleMetaTag = 'article:published_time' | 'article:modified_time' | 'article:author' | 'article:section' | 'article:tag';
3
+ type OpenGraphSiteMetaTag = 'site_name' | 'locale';
4
+ type OpenGraphPageMetaTag = 'type' | 'url' | 'title' | 'description' | OpenGraphImageMetaTag | OpenGraphArticleMetaTag;
5
+ type OpenGraphMetaTag = OpenGraphSiteMetaTag | OpenGraphPageMetaTag;
6
+ export type OpenGraphType = 'website' | 'article';
7
+ export interface IOpenGraphMetaItem {
8
+ property: `og:${OpenGraphMetaTag}`;
9
+ content: string;
10
+ }
11
+ export {};
@@ -1,13 +1,2 @@
1
- import { IHrefLang, ILocale, ISeoMetadata, IStructuredData, Nullable } from '../../types';
2
- interface ISeoData {
3
- locale: Nullable<ILocale['code']>;
4
- meta: {
5
- title: Nullable<ISeoMetadata['title']>;
6
- description: Nullable<ISeoMetadata['description']>;
7
- };
8
- canonicalUrl: Nullable<string>;
9
- hrefLangs: IHrefLang[];
10
- structuredData: Nullable<IStructuredData>;
11
- }
12
- export declare function extractSeoData(pageData: unknown, pageContext?: unknown): ISeoData;
13
- export {};
1
+ import { ISeo } from '../../types';
2
+ export declare function buildSeoFromStrapi(pageData: unknown, pageContext?: unknown): ISeo;
@@ -1,19 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const index = require("../index-C6MG_f24.js");
4
- const index$1 = require("../index-P_fDAJVz.js");
5
- const index$2 = require("../index-CnVcCa5O.js");
4
+ const index$1 = require("../index-BKWX6mIo.js");
5
+ const index$2 = require("../index-DHKoOk4o.js");
6
6
  const index$3 = require("../index-ov4J7p3D.js");
7
7
  const index$4 = require("../index-CAjUjAgI.js");
8
8
  const index$5 = require("../index-CbuiYkSg.js");
9
9
  exports.Animation = index.Animation;
10
- exports.extractSeoData = index$1.extractSeoData;
10
+ exports.buildSeoFromStrapi = index$1.buildSeoFromStrapi;
11
11
  exports.getLocale = index$1.getLocale;
12
12
  exports.getLocales = index$1.getLocales;
13
13
  exports.getNavigation = index$1.getNavigation;
14
14
  exports.getSiteName = index$1.getSiteName;
15
15
  exports.buildGameReviewSchema = index$2.buildGameReviewSchema;
16
16
  exports.buildGraph = index$2.buildGraph;
17
+ exports.buildOpenGraphMeta = index$2.buildOpenGraphMeta;
17
18
  exports.buildOrganizationSchema = index$2.buildOrganizationSchema;
18
19
  exports.buildWebpageSchema = index$2.buildWebpageSchema;
19
20
  exports.buildWebsiteSchema = index$2.buildWebsiteSchema;
@@ -2,7 +2,7 @@ export * from './animation';
2
2
  export * from './api';
3
3
  export * from './currency';
4
4
  export * from './date';
5
- export * from './json-ld';
5
+ export * from './seo';
6
6
  export * from './navigation';
7
7
  export * from './numbers';
8
8
  export * from './sorting';
@@ -1,6 +1,6 @@
1
1
  import { A } from "../index-BJRvnR8Q.mjs";
2
- import { e, a, b, c, g } from "../index-MnQnVvsM.mjs";
3
- import { k, d, e as e2, j, f, g as g2, h, l, i, c as c2, b as b2, a as a2, r } from "../index-CoNbTY7l.mjs";
2
+ import { d, a, b, c, g } from "../index-B--qmL1V.mjs";
3
+ import { k, d as d2, l, e, j, f, g as g2, h, m, i, c as c2, b as b2, a as a2, r } from "../index-BTfTkIed.mjs";
4
4
  import { f as f2, b as b3, a as a3, g as g3, r as r2, t } from "../index-BPthShL-.mjs";
5
5
  import { a as a4, b as b4, c as c3, i as i2 } from "../index-CQC6DRGf.mjs";
6
6
  import { D, L } from "../index-BRVKhbs6.mjs";
@@ -10,12 +10,13 @@ export {
10
10
  L as LIGHT_THEME_COLOR,
11
11
  a4 as buildCanonicalUrl,
12
12
  k as buildGameReviewSchema,
13
- d as buildGraph,
14
- e2 as buildOrganizationSchema,
13
+ d2 as buildGraph,
14
+ l as buildOpenGraphMeta,
15
+ e as buildOrganizationSchema,
15
16
  b4 as buildPath,
17
+ d as buildSeoFromStrapi,
16
18
  j as buildWebpageSchema,
17
19
  f as buildWebsiteSchema,
18
- e as extractSeoData,
19
20
  f2 as formatDate,
20
21
  b3 as formatNumber,
21
22
  g2 as getCurrencySymbol,
@@ -25,7 +26,7 @@ export {
25
26
  a as getLocale,
26
27
  b as getLocales,
27
28
  c as getNavigation,
28
- l as getSeededRandomComparator,
29
+ m as getSeededRandomComparator,
29
30
  g as getSiteName,
30
31
  c3 as isAbsolutePath,
31
32
  i2 as isRelativePath,
@@ -0,0 +1,2 @@
1
+ export * from './json-ld';
2
+ export * from './open-graph';
@@ -1,4 +1,4 @@
1
- import { GameSchema, ILocale, ISiteLogo, IStructuredData, Nullable, OrganizationSchema, ReviewSchema, Schema, Schemas, WebPageSchema, WebSiteSchema } from '../../types';
1
+ import { GameSchema, ILocale, ISiteLogo, IStructuredData, Nullable, OrganizationSchema, ReviewSchema, Schema, Schemas, WebPageSchema, WebSiteSchema } from '../../../types';
2
2
  export declare function buildGraph(schemas: Schemas): Schema[];
3
3
  interface BuildOrganizationSchemaParams {
4
4
  site: {
@@ -0,0 +1,15 @@
1
+ import { ILocale, IOpenGraph, IOpenGraphMetaItem } from '../../../types';
2
+ interface BuildOpenGraphParams {
3
+ site: {
4
+ name: string;
5
+ };
6
+ page: {
7
+ url: string;
8
+ title: string;
9
+ description: string;
10
+ };
11
+ lang: ILocale['code'];
12
+ content?: IOpenGraph['content'];
13
+ }
14
+ export declare function buildOpenGraphMeta(params: BuildOpenGraphParams): IOpenGraphMetaItem[];
15
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@anywayseo/tools",
3
3
  "description": "Shared UI Components and Modules",
4
- "version": "6.1.0",
4
+ "version": "6.2.0",
5
5
  "keywords": [
6
6
  "react",
7
7
  "ui",
@@ -1,14 +0,0 @@
1
- import { IHrefLang, ILocale, ISeoMetadata, IStructuredData, Nullable } from '../../types';
2
- export interface ISeoMetaItemPlaceholders {
3
- siteName: string;
4
- currentYear: string;
5
- currentMonth: string;
6
- }
7
- type SeoMetaItemGetter = (placeholders: ISeoMetaItemPlaceholders) => string;
8
- export type SeoLocale = Nullable<ILocale['code']>;
9
- export type SeoTitle = Nullable<ISeoMetadata['title'] | SeoMetaItemGetter>;
10
- export type SeoDescription = Nullable<ISeoMetadata['description'] | SeoMetaItemGetter>;
11
- export type SeoCanonical = Nullable<string>;
12
- export type SeoHrefLangs = IHrefLang[];
13
- export type SeoStructuredData = Nullable<IStructuredData>;
14
- export {};
File without changes