strapi-plugin-blogseo 1.1.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 (33) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -0
  3. package/dist/admin/Settings-BJbpMBlx.mjs +149 -0
  4. package/dist/admin/Settings-C3-8r0LW.js +149 -0
  5. package/dist/admin/en-CEwYiwKv.mjs +8 -0
  6. package/dist/admin/en-DXs_qePG.js +8 -0
  7. package/dist/admin/index.js +68 -0
  8. package/dist/admin/index.mjs +68 -0
  9. package/dist/admin/src/components/Initializer.d.ts +5 -0
  10. package/dist/admin/src/components/PluginIcon.d.ts +2 -0
  11. package/dist/admin/src/index.d.ts +3 -0
  12. package/dist/admin/src/pages/Settings.d.ts +2 -0
  13. package/dist/admin/src/pluginId.d.ts +1 -0
  14. package/dist/admin/src/utils/getTranslation.d.ts +2 -0
  15. package/dist/server/index.js +206 -0
  16. package/dist/server/index.mjs +206 -0
  17. package/dist/server/src/bootstrap.d.ts +5 -0
  18. package/dist/server/src/config/index.d.ts +7 -0
  19. package/dist/server/src/content-types/index.d.ts +2 -0
  20. package/dist/server/src/controllers/blogseo.d.ts +11 -0
  21. package/dist/server/src/controllers/index.d.ts +12 -0
  22. package/dist/server/src/destroy.d.ts +5 -0
  23. package/dist/server/src/index.d.ts +98 -0
  24. package/dist/server/src/middlewares/index.d.ts +2 -0
  25. package/dist/server/src/policies/index.d.ts +2 -0
  26. package/dist/server/src/register.d.ts +5 -0
  27. package/dist/server/src/routes/admin/index.d.ts +12 -0
  28. package/dist/server/src/routes/content-api/index.d.ts +12 -0
  29. package/dist/server/src/routes/index.d.ts +25 -0
  30. package/dist/server/src/services/blogseo.d.ts +43 -0
  31. package/dist/server/src/services/index.d.ts +43 -0
  32. package/dist/server/src/utils/getService.d.ts +3 -0
  33. package/package.json +89 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vincent JOSSE (BlogSEO)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # BlogSEO for Strapi
2
+
3
+ Connect your Strapi project to [BlogSEO](https://www.blogseo.io) — the AI-powered SEO platform that writes, illustrates and publishes SEO-optimized blog articles to your site on autopilot, and builds high-quality backlinks to grow your organic traffic.
4
+
5
+ This plugin links your Strapi instance to your BlogSEO account in a couple of clicks: no manual API-token creation, no copy-pasting content-type IDs between dashboards.
6
+
7
+ ## What is BlogSEO?
8
+
9
+ [BlogSEO](https://www.blogseo.io) helps businesses grow their organic search traffic end to end:
10
+
11
+ - **AI-written SEO articles** — long-form, SEO-optimized articles researched and written for your niche, in 100+ languages, with AI-generated cover and inline images.
12
+ - **High-quality backlinks** — grow your Domain Rating with backlink building, and track your backlink profile over time.
13
+ - **Publishing on autopilot** — articles are scheduled and published straight into your CMS (Strapi, WordPress, Shopify, Ghost, and many more), formatted for your content model.
14
+ - **SEO analytics** — keyword tracking and Google Search Console insights to measure what your content brings in.
15
+
16
+ The plugin is free and open source. Publishing requires a [BlogSEO](https://www.blogseo.io) account.
17
+
18
+ ## What the plugin does
19
+
20
+ - Adds a **BlogSEO** page under **Settings** in your Strapi admin panel.
21
+ - Lets you connect with a single **connection key** pasted from your BlogSEO dashboard.
22
+ - Automatically creates the **Strapi API token** BlogSEO publishes with — you never have to create or handle one manually, and disconnecting revokes it.
23
+ - Detects your **content types and locales** and registers everything with BlogSEO in one click.
24
+ - Shows the **connection status** and lets you disconnect (revoking the token) at any time.
25
+
26
+ ## Requirements
27
+
28
+ - Strapi **v5**
29
+ - A [BlogSEO account](https://www.blogseo.io)
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ npm install strapi-plugin-blogseo
35
+ # or
36
+ yarn add strapi-plugin-blogseo
37
+ ```
38
+
39
+ Then rebuild your admin panel:
40
+
41
+ ```bash
42
+ npm run build
43
+ ```
44
+
45
+ The plugin is enabled automatically once installed. No configuration file changes are required.
46
+
47
+ ## Getting started
48
+
49
+ 1. In your [BlogSEO dashboard](https://app.blogseo.io), go to **Integrations → Strapi** and choose **Connect via plugin** to generate a connection key.
50
+ 2. In your Strapi admin panel, go to **Settings → BlogSEO**, paste the key, pick the collection your articles should be published into, and click **Connect**.
51
+ 3. That's it — BlogSEO now publishes your scheduled articles straight into that collection.
52
+
53
+ Full walkthrough: [BlogSEO Strapi integration docs](https://www.blogseo.io/docs/integrations/strapi).
54
+
55
+ ## Advanced configuration
56
+
57
+ All options are optional and go in `config/plugins.ts`:
58
+
59
+ ```ts
60
+ export default {
61
+ "blogseo": {
62
+ enabled: true,
63
+ config: {
64
+ // Override the BlogSEO API endpoint (self-hosted / staging setups)
65
+ blogSeoApiUrl: "https://app.blogseo.io",
66
+ },
67
+ },
68
+ };
69
+ ```
70
+
71
+ ## Support
72
+
73
+ - Website: [https://www.blogseo.io](https://www.blogseo.io)
74
+ - Documentation: [https://www.blogseo.io/docs/integrations/strapi](https://www.blogseo.io/docs/integrations/strapi)
75
+ - Email: [support@blogseo.io](mailto:support@blogseo.io)
76
+
77
+ Found a bug or have a feature request? [Open an issue](https://github.com/baballev/blogseo-strapi-plugin/issues).
78
+
79
+ ## License
80
+
81
+ [MIT](LICENSE)
@@ -0,0 +1,149 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { Main, Box, Flex, Typography, Button, Field, SingleSelect, SingleSelectOption } from "@strapi/design-system";
4
+ import { useFetchClient, useNotification, Page, Layouts } from "@strapi/strapi/admin";
5
+ const PLUGIN_BASE = "/blogseo";
6
+ const extractErrorMessage = (error, fallback) => {
7
+ const data = error?.response?.data;
8
+ return data?.error?.message ?? fallback;
9
+ };
10
+ const Settings = () => {
11
+ const { get, post } = useFetchClient();
12
+ const { toggleNotification } = useNotification();
13
+ const [isLoading, setIsLoading] = useState(true);
14
+ const [isSubmitting, setIsSubmitting] = useState(false);
15
+ const [status, setStatus] = useState(null);
16
+ const [contentTypes, setContentTypes] = useState([]);
17
+ const [apiKey, setApiKey] = useState("");
18
+ const [pluralApiId, setPluralApiId] = useState("");
19
+ useEffect(() => {
20
+ const load = async () => {
21
+ try {
22
+ const [statusRes, contentTypesRes] = await Promise.all([
23
+ get(`${PLUGIN_BASE}/status`),
24
+ get(`${PLUGIN_BASE}/content-types`)
25
+ ]);
26
+ setStatus(statusRes.data);
27
+ setContentTypes(contentTypesRes.data.contentTypes ?? []);
28
+ if (contentTypesRes.data.contentTypes?.length)
29
+ setPluralApiId(contentTypesRes.data.contentTypes[0].pluralApiId);
30
+ } catch {
31
+ toggleNotification({ type: "danger", message: "Could not load BlogSEO settings." });
32
+ } finally {
33
+ setIsLoading(false);
34
+ }
35
+ };
36
+ load();
37
+ }, [get, toggleNotification]);
38
+ const handleConnect = async () => {
39
+ if (!apiKey.trim())
40
+ return toggleNotification({ type: "warning", message: "Paste your BlogSEO connection key first." });
41
+ if (!pluralApiId)
42
+ return toggleNotification({ type: "warning", message: "Pick a collection to publish into." });
43
+ setIsSubmitting(true);
44
+ try {
45
+ const { data } = await post(
46
+ `${PLUGIN_BASE}/connect`,
47
+ { apiKey: apiKey.trim(), pluralApiId }
48
+ );
49
+ setStatus({ connected: true, siteUrl: data.siteUrl, pluralApiId });
50
+ setApiKey("");
51
+ toggleNotification({
52
+ type: "success",
53
+ message: "Connected to BlogSEO! Articles will now publish into this Strapi."
54
+ });
55
+ } catch (error) {
56
+ toggleNotification({
57
+ type: "danger",
58
+ message: extractErrorMessage(error, "Failed to connect to BlogSEO.")
59
+ });
60
+ } finally {
61
+ setIsSubmitting(false);
62
+ }
63
+ };
64
+ const handleDisconnect = async () => {
65
+ setIsSubmitting(true);
66
+ try {
67
+ await post(`${PLUGIN_BASE}/disconnect`, {});
68
+ setStatus({ connected: false, siteUrl: null, pluralApiId: null });
69
+ toggleNotification({ type: "success", message: "Disconnected from BlogSEO." });
70
+ } catch {
71
+ toggleNotification({ type: "danger", message: "Failed to disconnect." });
72
+ } finally {
73
+ setIsSubmitting(false);
74
+ }
75
+ };
76
+ if (isLoading) return /* @__PURE__ */ jsx(Page.Loading, {});
77
+ return /* @__PURE__ */ jsxs(Main, { children: [
78
+ /* @__PURE__ */ jsx(
79
+ Layouts.Header,
80
+ {
81
+ title: "BlogSEO",
82
+ subtitle: "Publish AI-generated SEO articles and build backlinks straight into this Strapi."
83
+ }
84
+ ),
85
+ /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(Box, { background: "neutral0", padding: 6, shadow: "tableShadow", hasRadius: true, children: status?.connected ? /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
86
+ /* @__PURE__ */ jsx(Typography, { variant: "delta", children: "Connected to BlogSEO" }),
87
+ /* @__PURE__ */ jsxs(Box, { children: [
88
+ /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: "Publishing into " }),
89
+ /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: status.pluralApiId ?? "—" }),
90
+ status.siteUrl ? /* @__PURE__ */ jsxs(Typography, { textColor: "neutral600", children: [
91
+ " · ",
92
+ status.siteUrl
93
+ ] }) : null
94
+ ] }),
95
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Button, { variant: "danger-light", onClick: handleDisconnect, loading: isSubmitting, children: "Disconnect" }) })
96
+ ] }) : /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
97
+ /* @__PURE__ */ jsx(Typography, { variant: "delta", children: "Connect your BlogSEO account" }),
98
+ /* @__PURE__ */ jsxs(
99
+ Field.Root,
100
+ {
101
+ name: "apiKey",
102
+ hint: "Generate this in your BlogSEO dashboard → Integrations → Strapi → “Connect with the Strapi plugin”.",
103
+ children: [
104
+ /* @__PURE__ */ jsx(Field.Label, { children: "BlogSEO connection key" }),
105
+ /* @__PURE__ */ jsx(
106
+ Field.Input,
107
+ {
108
+ type: "password",
109
+ value: apiKey,
110
+ onChange: (event) => setApiKey(event.target.value),
111
+ placeholder: "blogseo_sp_..."
112
+ }
113
+ ),
114
+ /* @__PURE__ */ jsx(Field.Hint, {})
115
+ ]
116
+ }
117
+ ),
118
+ /* @__PURE__ */ jsxs(
119
+ Field.Root,
120
+ {
121
+ name: "contentType",
122
+ hint: "New articles from BlogSEO are created as entries here.",
123
+ children: [
124
+ /* @__PURE__ */ jsx(Field.Label, { children: "Collection to publish into" }),
125
+ /* @__PURE__ */ jsx(
126
+ SingleSelect,
127
+ {
128
+ value: pluralApiId,
129
+ onChange: (value) => setPluralApiId(String(value)),
130
+ placeholder: "Select a collection",
131
+ children: contentTypes.map((contentType) => /* @__PURE__ */ jsxs(SingleSelectOption, { value: contentType.pluralApiId, children: [
132
+ contentType.displayName,
133
+ " (",
134
+ contentType.pluralApiId,
135
+ ")"
136
+ ] }, contentType.uid))
137
+ }
138
+ ),
139
+ /* @__PURE__ */ jsx(Field.Hint, {})
140
+ ]
141
+ }
142
+ ),
143
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Button, { onClick: handleConnect, loading: isSubmitting, disabled: !apiKey || !pluralApiId, children: "Connect" }) })
144
+ ] }) }) })
145
+ ] });
146
+ };
147
+ export {
148
+ Settings as default
149
+ };
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const designSystem = require("@strapi/design-system");
6
+ const admin = require("@strapi/strapi/admin");
7
+ const PLUGIN_BASE = "/blogseo";
8
+ const extractErrorMessage = (error, fallback) => {
9
+ const data = error?.response?.data;
10
+ return data?.error?.message ?? fallback;
11
+ };
12
+ const Settings = () => {
13
+ const { get, post } = admin.useFetchClient();
14
+ const { toggleNotification } = admin.useNotification();
15
+ const [isLoading, setIsLoading] = react.useState(true);
16
+ const [isSubmitting, setIsSubmitting] = react.useState(false);
17
+ const [status, setStatus] = react.useState(null);
18
+ const [contentTypes, setContentTypes] = react.useState([]);
19
+ const [apiKey, setApiKey] = react.useState("");
20
+ const [pluralApiId, setPluralApiId] = react.useState("");
21
+ react.useEffect(() => {
22
+ const load = async () => {
23
+ try {
24
+ const [statusRes, contentTypesRes] = await Promise.all([
25
+ get(`${PLUGIN_BASE}/status`),
26
+ get(`${PLUGIN_BASE}/content-types`)
27
+ ]);
28
+ setStatus(statusRes.data);
29
+ setContentTypes(contentTypesRes.data.contentTypes ?? []);
30
+ if (contentTypesRes.data.contentTypes?.length)
31
+ setPluralApiId(contentTypesRes.data.contentTypes[0].pluralApiId);
32
+ } catch {
33
+ toggleNotification({ type: "danger", message: "Could not load BlogSEO settings." });
34
+ } finally {
35
+ setIsLoading(false);
36
+ }
37
+ };
38
+ load();
39
+ }, [get, toggleNotification]);
40
+ const handleConnect = async () => {
41
+ if (!apiKey.trim())
42
+ return toggleNotification({ type: "warning", message: "Paste your BlogSEO connection key first." });
43
+ if (!pluralApiId)
44
+ return toggleNotification({ type: "warning", message: "Pick a collection to publish into." });
45
+ setIsSubmitting(true);
46
+ try {
47
+ const { data } = await post(
48
+ `${PLUGIN_BASE}/connect`,
49
+ { apiKey: apiKey.trim(), pluralApiId }
50
+ );
51
+ setStatus({ connected: true, siteUrl: data.siteUrl, pluralApiId });
52
+ setApiKey("");
53
+ toggleNotification({
54
+ type: "success",
55
+ message: "Connected to BlogSEO! Articles will now publish into this Strapi."
56
+ });
57
+ } catch (error) {
58
+ toggleNotification({
59
+ type: "danger",
60
+ message: extractErrorMessage(error, "Failed to connect to BlogSEO.")
61
+ });
62
+ } finally {
63
+ setIsSubmitting(false);
64
+ }
65
+ };
66
+ const handleDisconnect = async () => {
67
+ setIsSubmitting(true);
68
+ try {
69
+ await post(`${PLUGIN_BASE}/disconnect`, {});
70
+ setStatus({ connected: false, siteUrl: null, pluralApiId: null });
71
+ toggleNotification({ type: "success", message: "Disconnected from BlogSEO." });
72
+ } catch {
73
+ toggleNotification({ type: "danger", message: "Failed to disconnect." });
74
+ } finally {
75
+ setIsSubmitting(false);
76
+ }
77
+ };
78
+ if (isLoading) return /* @__PURE__ */ jsxRuntime.jsx(admin.Page.Loading, {});
79
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { children: [
80
+ /* @__PURE__ */ jsxRuntime.jsx(
81
+ admin.Layouts.Header,
82
+ {
83
+ title: "BlogSEO",
84
+ subtitle: "Publish AI-generated SEO articles and build backlinks straight into this Strapi."
85
+ }
86
+ ),
87
+ /* @__PURE__ */ jsxRuntime.jsx(admin.Layouts.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "neutral0", padding: 6, shadow: "tableShadow", hasRadius: true, children: status?.connected ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
88
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "Connected to BlogSEO" }),
89
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
90
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: "Publishing into " }),
91
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: status.pluralApiId ?? "—" }),
92
+ status.siteUrl ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { textColor: "neutral600", children: [
93
+ " · ",
94
+ status.siteUrl
95
+ ] }) : null
96
+ ] }),
97
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", onClick: handleDisconnect, loading: isSubmitting, children: "Disconnect" }) })
98
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
99
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "Connect your BlogSEO account" }),
100
+ /* @__PURE__ */ jsxRuntime.jsxs(
101
+ designSystem.Field.Root,
102
+ {
103
+ name: "apiKey",
104
+ hint: "Generate this in your BlogSEO dashboard → Integrations → Strapi → “Connect with the Strapi plugin”.",
105
+ children: [
106
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "BlogSEO connection key" }),
107
+ /* @__PURE__ */ jsxRuntime.jsx(
108
+ designSystem.Field.Input,
109
+ {
110
+ type: "password",
111
+ value: apiKey,
112
+ onChange: (event) => setApiKey(event.target.value),
113
+ placeholder: "blogseo_sp_..."
114
+ }
115
+ ),
116
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
117
+ ]
118
+ }
119
+ ),
120
+ /* @__PURE__ */ jsxRuntime.jsxs(
121
+ designSystem.Field.Root,
122
+ {
123
+ name: "contentType",
124
+ hint: "New articles from BlogSEO are created as entries here.",
125
+ children: [
126
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Collection to publish into" }),
127
+ /* @__PURE__ */ jsxRuntime.jsx(
128
+ designSystem.SingleSelect,
129
+ {
130
+ value: pluralApiId,
131
+ onChange: (value) => setPluralApiId(String(value)),
132
+ placeholder: "Select a collection",
133
+ children: contentTypes.map((contentType) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.SingleSelectOption, { value: contentType.pluralApiId, children: [
134
+ contentType.displayName,
135
+ " (",
136
+ contentType.pluralApiId,
137
+ ")"
138
+ ] }, contentType.uid))
139
+ }
140
+ ),
141
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
142
+ ]
143
+ }
144
+ ),
145
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConnect, loading: isSubmitting, disabled: !apiKey || !pluralApiId, children: "Connect" }) })
146
+ ] }) }) })
147
+ ] });
148
+ };
149
+ exports.default = Settings;
@@ -0,0 +1,8 @@
1
+ const en = {
2
+ "plugin.name": "BlogSEO",
3
+ "settings.section": "BlogSEO",
4
+ "settings.link": "Configuration"
5
+ };
6
+ export {
7
+ en as default
8
+ };
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const en = {
4
+ "plugin.name": "BlogSEO",
5
+ "settings.section": "BlogSEO",
6
+ "settings.link": "Configuration"
7
+ };
8
+ exports.default = en;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const react = require("react");
4
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
5
+ const v = glob[path];
6
+ if (v) {
7
+ return typeof v === "function" ? v() : Promise.resolve(v);
8
+ }
9
+ return new Promise((_, reject) => {
10
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
11
+ reject.bind(
12
+ null,
13
+ new Error(
14
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
15
+ )
16
+ )
17
+ );
18
+ });
19
+ };
20
+ const PLUGIN_ID = "blogseo";
21
+ const getTranslation = (id) => `${PLUGIN_ID}.${id}`;
22
+ const Initializer = ({ setPlugin }) => {
23
+ const ref = react.useRef(setPlugin);
24
+ react.useEffect(() => {
25
+ ref.current(PLUGIN_ID);
26
+ }, []);
27
+ return null;
28
+ };
29
+ const plugin = {
30
+ register(app) {
31
+ app.createSettingSection(
32
+ {
33
+ id: PLUGIN_ID,
34
+ intlLabel: { id: getTranslation("settings.section"), defaultMessage: "BlogSEO" }
35
+ },
36
+ [
37
+ {
38
+ intlLabel: { id: getTranslation("settings.link"), defaultMessage: "Configuration" },
39
+ id: PLUGIN_ID,
40
+ to: `/settings/${PLUGIN_ID}`,
41
+ Component: () => Promise.resolve().then(() => require("./Settings-C3-8r0LW.js")),
42
+ permissions: []
43
+ }
44
+ ]
45
+ );
46
+ app.registerPlugin({
47
+ id: PLUGIN_ID,
48
+ initializer: Initializer,
49
+ isReady: false,
50
+ name: PLUGIN_ID
51
+ });
52
+ },
53
+ registerTrads({ locales }) {
54
+ return Promise.all(
55
+ locales.map(async (locale) => {
56
+ try {
57
+ const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-DXs_qePG.js")) }), `./translations/${locale}.json`, 3);
58
+ const newData = {};
59
+ for (const key of Object.keys(data)) newData[getTranslation(key)] = data[key];
60
+ return { data: newData, locale };
61
+ } catch {
62
+ return { data: {}, locale };
63
+ }
64
+ })
65
+ );
66
+ }
67
+ };
68
+ exports.default = plugin;
@@ -0,0 +1,68 @@
1
+ import { useRef, useEffect } from "react";
2
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
3
+ const v = glob[path];
4
+ if (v) {
5
+ return typeof v === "function" ? v() : Promise.resolve(v);
6
+ }
7
+ return new Promise((_, reject) => {
8
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
9
+ reject.bind(
10
+ null,
11
+ new Error(
12
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
13
+ )
14
+ )
15
+ );
16
+ });
17
+ };
18
+ const PLUGIN_ID = "blogseo";
19
+ const getTranslation = (id) => `${PLUGIN_ID}.${id}`;
20
+ const Initializer = ({ setPlugin }) => {
21
+ const ref = useRef(setPlugin);
22
+ useEffect(() => {
23
+ ref.current(PLUGIN_ID);
24
+ }, []);
25
+ return null;
26
+ };
27
+ const plugin = {
28
+ register(app) {
29
+ app.createSettingSection(
30
+ {
31
+ id: PLUGIN_ID,
32
+ intlLabel: { id: getTranslation("settings.section"), defaultMessage: "BlogSEO" }
33
+ },
34
+ [
35
+ {
36
+ intlLabel: { id: getTranslation("settings.link"), defaultMessage: "Configuration" },
37
+ id: PLUGIN_ID,
38
+ to: `/settings/${PLUGIN_ID}`,
39
+ Component: () => import("./Settings-BJbpMBlx.mjs"),
40
+ permissions: []
41
+ }
42
+ ]
43
+ );
44
+ app.registerPlugin({
45
+ id: PLUGIN_ID,
46
+ initializer: Initializer,
47
+ isReady: false,
48
+ name: PLUGIN_ID
49
+ });
50
+ },
51
+ registerTrads({ locales }) {
52
+ return Promise.all(
53
+ locales.map(async (locale) => {
54
+ try {
55
+ const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-CEwYiwKv.mjs") }), `./translations/${locale}.json`, 3);
56
+ const newData = {};
57
+ for (const key of Object.keys(data)) newData[getTranslation(key)] = data[key];
58
+ return { data: newData, locale };
59
+ } catch {
60
+ return { data: {}, locale };
61
+ }
62
+ })
63
+ );
64
+ }
65
+ };
66
+ export {
67
+ plugin as default
68
+ };
@@ -0,0 +1,5 @@
1
+ type InitializerProps = {
2
+ setPlugin: (id: string) => void;
3
+ };
4
+ declare const Initializer: ({ setPlugin }: InitializerProps) => null;
5
+ export { Initializer };
@@ -0,0 +1,2 @@
1
+ declare const PluginIcon: () => import("react").JSX.Element;
2
+ export { PluginIcon };
@@ -0,0 +1,3 @@
1
+ import { StrapiApp } from '@strapi/strapi/admin';
2
+ declare const plugin: StrapiApp["appPlugins"][string];
3
+ export default plugin;
@@ -0,0 +1,2 @@
1
+ declare const Settings: () => import("react").JSX.Element;
2
+ export default Settings;
@@ -0,0 +1 @@
1
+ export declare const PLUGIN_ID = "blogseo";
@@ -0,0 +1,2 @@
1
+ declare const getTranslation: (id: string) => string;
2
+ export { getTranslation };