@uptrademedia/site-kit 1.0.4 → 1.0.7
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.
- package/README.md +96 -25
- package/dist/analytics/index.js +7 -7
- package/dist/analytics/index.mjs +3 -3
- package/dist/api-QUIPJJCX.js +77 -0
- package/dist/api-QUIPJJCX.js.map +1 -0
- package/dist/api-V3BA5PMX.mjs +4 -0
- package/dist/api-V3BA5PMX.mjs.map +1 -0
- package/dist/blog/index.d.mts +160 -5
- package/dist/blog/index.d.ts +160 -5
- package/dist/blog/index.js +1166 -18
- package/dist/blog/index.js.map +1 -1
- package/dist/blog/index.mjs +1156 -18
- package/dist/blog/index.mjs.map +1 -1
- package/dist/blog/server.d.mts +229 -0
- package/dist/blog/server.d.ts +229 -0
- package/dist/blog/server.js +692 -0
- package/dist/blog/server.js.map +1 -0
- package/dist/blog/server.mjs +666 -0
- package/dist/blog/server.mjs.map +1 -0
- package/dist/{chunk-FKVJOT2F.mjs → chunk-42EXHJTC.mjs} +196 -7
- package/dist/chunk-42EXHJTC.mjs.map +1 -0
- package/dist/{scanner-AZV5I6US.mjs → chunk-44OMJFCG.mjs} +354 -14
- package/dist/chunk-44OMJFCG.mjs.map +1 -0
- package/dist/chunk-4TGJYNHV.js +981 -0
- package/dist/chunk-4TGJYNHV.js.map +1 -0
- package/dist/chunk-4XPGGLVP.mjs +53 -0
- package/dist/{chunk-NYKRE2FL.mjs.map → chunk-4XPGGLVP.mjs.map} +1 -1
- package/dist/{generators-TO2FKJR6.mjs → chunk-6ONUXZDO.mjs} +26 -9
- package/dist/chunk-6ONUXZDO.mjs.map +1 -0
- package/dist/chunk-CG53ASWX.mjs +729 -0
- package/dist/chunk-CG53ASWX.mjs.map +1 -0
- package/dist/{scanner-ETJAMIT7.js → chunk-DERI27QC.js} +448 -102
- package/dist/chunk-DERI27QC.js.map +1 -0
- package/dist/chunk-DYM5ML2V.mjs +1518 -0
- package/dist/chunk-DYM5ML2V.mjs.map +1 -0
- package/dist/chunk-FLZZOX44.js +1526 -0
- package/dist/chunk-FLZZOX44.js.map +1 -0
- package/dist/{chunk-7H6I3ECV.mjs → chunk-FQVGK746.mjs} +63 -3
- package/dist/chunk-FQVGK746.mjs.map +1 -0
- package/dist/{chunk-GQ6ZOU2N.mjs → chunk-JGQPAXTL.mjs} +4 -4
- package/dist/{chunk-GQ6ZOU2N.mjs.map → chunk-JGQPAXTL.mjs.map} +1 -1
- package/dist/{chunk-V3F5J6CV.js → chunk-JUEVN4Q4.js} +196 -7
- package/dist/chunk-JUEVN4Q4.js.map +1 -0
- package/dist/chunk-KKMGTT7F.mjs +968 -0
- package/dist/chunk-KKMGTT7F.mjs.map +1 -0
- package/dist/{chunk-XQJX252G.mjs → chunk-MB3WR5KJ.mjs} +28 -18
- package/dist/chunk-MB3WR5KJ.mjs.map +1 -0
- package/dist/{chunk-2IHTEKHU.mjs → chunk-QD5CN2OI.mjs} +16 -7
- package/dist/chunk-QD5CN2OI.mjs.map +1 -0
- package/dist/chunk-QD66FTXZ.mjs +278 -0
- package/dist/chunk-QD66FTXZ.mjs.map +1 -0
- package/dist/{chunk-SBVEYCSV.js → chunk-QQB4FO4Q.js} +7 -7
- package/dist/{chunk-SBVEYCSV.js.map → chunk-QQB4FO4Q.js.map} +1 -1
- package/dist/{generators-YZWIGHCO.js → chunk-S2GXR5HY.js} +26 -9
- package/dist/chunk-S2GXR5HY.js.map +1 -0
- package/dist/{chunk-O2OHHBUD.js → chunk-TDK7DLCH.js} +30 -20
- package/dist/chunk-TDK7DLCH.js.map +1 -0
- package/dist/chunk-UJQ73OS6.js +282 -0
- package/dist/chunk-UJQ73OS6.js.map +1 -0
- package/dist/{chunk-QP5NCO2E.js → chunk-VDI7KYME.js} +67 -2
- package/dist/chunk-VDI7KYME.js.map +1 -0
- package/dist/chunk-VOR53RUR.js +753 -0
- package/dist/chunk-VOR53RUR.js.map +1 -0
- package/dist/{chunk-GAJLEDRD.js → chunk-ZKJ7JKFV.js} +16 -7
- package/dist/chunk-ZKJ7JKFV.js.map +1 -0
- package/dist/chunk-ZSMWDLMK.js +63 -0
- package/dist/{chunk-EQCVQC35.js.map → chunk-ZSMWDLMK.js.map} +1 -1
- package/dist/cli/index.js +37269 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +37233 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/commerce/index.js +1 -1
- package/dist/commerce/index.mjs +1 -1
- package/dist/commerce/server.d.mts +12 -3
- package/dist/commerce/server.d.ts +12 -3
- package/dist/commerce/server.js +71 -70
- package/dist/commerce/server.js.map +1 -1
- package/dist/commerce/server.mjs +71 -70
- package/dist/commerce/server.mjs.map +1 -1
- package/dist/engage/index.d.mts +6 -4
- package/dist/engage/index.d.ts +6 -4
- package/dist/engage/index.js +8 -4
- package/dist/engage/index.mjs +2 -2
- package/dist/forms/index.js +1 -1
- package/dist/forms/index.mjs +1 -1
- package/dist/generators-5EU4PTVF.js +33 -0
- package/dist/generators-5EU4PTVF.js.map +1 -0
- package/dist/generators-TYPILCWD.mjs +4 -0
- package/dist/generators-TYPILCWD.mjs.map +1 -0
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.d.mts +155 -5
- package/dist/index.d.ts +155 -5
- package/dist/index.js +979 -50
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +821 -8
- package/dist/index.mjs.map +1 -1
- package/dist/llms/index.d.mts +657 -0
- package/dist/llms/index.d.ts +657 -0
- package/dist/llms/index.js +101 -0
- package/dist/llms/index.js.map +1 -0
- package/dist/llms/index.mjs +4 -0
- package/dist/llms/index.mjs.map +1 -0
- package/dist/migrator-ARLHUNB3.mjs +4 -0
- package/dist/migrator-ARLHUNB3.mjs.map +1 -0
- package/dist/migrator-VZLBH3VY.js +37 -0
- package/dist/migrator-VZLBH3VY.js.map +1 -0
- package/dist/redirects/index.js +1 -1
- package/dist/redirects/index.mjs +1 -1
- package/dist/reputation/index.d.mts +57 -0
- package/dist/reputation/index.d.ts +57 -0
- package/dist/reputation/index.js +21 -0
- package/dist/reputation/index.js.map +1 -0
- package/dist/reputation/index.mjs +4 -0
- package/dist/reputation/index.mjs.map +1 -0
- package/dist/{routing-BWjUF7lp.d.ts → routing-CF91y6NO.d.ts} +1 -1
- package/dist/{routing-CgmRi9tD.d.mts → routing-CIOFpFCB.d.mts} +1 -1
- package/dist/scanner-7ZMUM2P5.mjs +4 -0
- package/dist/scanner-7ZMUM2P5.mjs.map +1 -0
- package/dist/scanner-OY7UF3WA.js +53 -0
- package/dist/scanner-OY7UF3WA.js.map +1 -0
- package/dist/seo/index.d.mts +267 -7
- package/dist/seo/index.d.ts +267 -7
- package/dist/seo/index.js +432 -24
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +400 -11
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo/server.d.mts +11 -4
- package/dist/seo/server.d.ts +11 -4
- package/dist/seo/server.js +17 -17
- package/dist/seo/server.mjs +3 -3
- package/dist/setup/client.js +1 -1
- package/dist/setup/client.mjs +1 -1
- package/dist/setup/index.js +3 -3
- package/dist/setup/index.mjs +2 -2
- package/dist/setup/server.js +3 -3
- package/dist/setup/server.mjs +2 -2
- package/dist/sitemap/index.js +2 -2
- package/dist/sitemap/index.js.map +1 -1
- package/dist/sitemap/index.mjs +2 -2
- package/dist/sitemap/index.mjs.map +1 -1
- package/dist/{types-C0pJGfbH.d.mts → types-D6FHAVWX.d.mts} +99 -3
- package/dist/{types-C0pJGfbH.d.ts → types-D6FHAVWX.d.ts} +99 -3
- package/dist/{types-BDojCvvL.d.mts → types-DI0jnhjJ.d.mts} +31 -8
- package/dist/{types-BDojCvvL.d.ts → types-DI0jnhjJ.d.ts} +31 -8
- package/dist/{types-BmzutFwy.d.ts → types-j8X4vUhB.d.mts} +19 -2
- package/dist/{types-BmzutFwy.d.mts → types-j8X4vUhB.d.ts} +19 -2
- package/dist/{web-vitals-BH55V7EJ.js → web-vitals-444RLW3B.js} +11 -11
- package/dist/{web-vitals-BH55V7EJ.js.map → web-vitals-444RLW3B.js.map} +1 -1
- package/dist/{web-vitals-RJYPWAR3.mjs → web-vitals-KPICZIEF.mjs} +3 -3
- package/dist/{web-vitals-RJYPWAR3.mjs.map → web-vitals-KPICZIEF.mjs.map} +1 -1
- package/package.json +22 -10
- package/dist/api-N35S3EES.js +0 -57
- package/dist/api-N35S3EES.js.map +0 -1
- package/dist/api-SYBTK7Z7.mjs +0 -4
- package/dist/api-SYBTK7Z7.mjs.map +0 -1
- package/dist/chunk-2IHTEKHU.mjs.map +0 -1
- package/dist/chunk-7H6I3ECV.mjs.map +0 -1
- package/dist/chunk-BGJLOJ7T.mjs +0 -605
- package/dist/chunk-BGJLOJ7T.mjs.map +0 -1
- package/dist/chunk-EQCVQC35.js +0 -35
- package/dist/chunk-FKVJOT2F.mjs.map +0 -1
- package/dist/chunk-GAJLEDRD.js.map +0 -1
- package/dist/chunk-NYKRE2FL.mjs +0 -31
- package/dist/chunk-O2OHHBUD.js.map +0 -1
- package/dist/chunk-QAYJV4KK.js +0 -608
- package/dist/chunk-QAYJV4KK.js.map +0 -1
- package/dist/chunk-QP5NCO2E.js.map +0 -1
- package/dist/chunk-V3F5J6CV.js.map +0 -1
- package/dist/chunk-XQJX252G.mjs.map +0 -1
- package/dist/generators-TO2FKJR6.mjs.map +0 -1
- package/dist/generators-YZWIGHCO.js.map +0 -1
- package/dist/migrator-V6KS75EA.mjs +0 -265
- package/dist/migrator-V6KS75EA.mjs.map +0 -1
- package/dist/migrator-XKM7YQCY.js +0 -272
- package/dist/migrator-XKM7YQCY.js.map +0 -1
- package/dist/scanner-AZV5I6US.mjs.map +0 -1
- package/dist/scanner-ETJAMIT7.js.map +0 -1
package/dist/seo/index.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { SitemapSync } from '../chunk-WPSRS352.mjs';
|
|
2
|
-
export { generateSitemap, getRedirect, getRobotsDirective, isIndexable } from '../chunk-
|
|
3
|
-
import { getSEOPageData, getABTest, recordABImpression, getSchemaMarkups, getFAQData, getInternalLinks, getContentBlock, getManagedScripts } from '../chunk-
|
|
4
|
-
import '../chunk-
|
|
2
|
+
export { generateSitemap, getRedirect, getRobotsDirective, isIndexable } from '../chunk-JGQPAXTL.mjs';
|
|
3
|
+
import { getSEOPageData, getABTest, recordABImpression, getSchemaMarkups, getEntityEnhancedSchema, getFAQData, getInternalLinks, getContentBlock, getEntities, getManagedScripts } from '../chunk-FQVGK746.mjs';
|
|
4
|
+
import '../chunk-4XPGGLVP.mjs';
|
|
5
|
+
import { cache } from 'react';
|
|
6
|
+
import 'server-only';
|
|
5
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
8
|
|
|
7
9
|
// src/seo/getManagedMetadata.ts
|
|
@@ -25,8 +27,8 @@ async function getManagedMetadata(options) {
|
|
|
25
27
|
} else if (fallback.title) {
|
|
26
28
|
metadata.title = fallback.title;
|
|
27
29
|
}
|
|
28
|
-
if (pageData.managed_description) {
|
|
29
|
-
metadata.description = pageData.managed_description;
|
|
30
|
+
if (pageData.managed_meta_description || pageData.managed_description) {
|
|
31
|
+
metadata.description = pageData.managed_meta_description || pageData.managed_description;
|
|
30
32
|
} else if (fallback.description) {
|
|
31
33
|
metadata.description = fallback.description;
|
|
32
34
|
}
|
|
@@ -45,7 +47,7 @@ async function getManagedMetadata(options) {
|
|
|
45
47
|
};
|
|
46
48
|
}
|
|
47
49
|
const ogTitle = pageData.managed_og_title || pageData.managed_title;
|
|
48
|
-
const ogDescription = pageData.managed_og_description || pageData.managed_description;
|
|
50
|
+
const ogDescription = pageData.managed_og_description || pageData.managed_meta_description || pageData.managed_description;
|
|
49
51
|
const ogImage = pageData.managed_og_image;
|
|
50
52
|
if (ogTitle || ogDescription || ogImage) {
|
|
51
53
|
metadata.openGraph = {
|
|
@@ -115,21 +117,235 @@ async function getManagedMetadataWithAB(options) {
|
|
|
115
117
|
}
|
|
116
118
|
return metadata;
|
|
117
119
|
}
|
|
120
|
+
function getSecureApiConfig() {
|
|
121
|
+
const apiUrl = process.env.UPTRADE_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL || "https://api.uptrademedia.com";
|
|
122
|
+
const apiKey = process.env.UPTRADE_API_KEY || "";
|
|
123
|
+
const projectId = process.env.UPTRADE_PROJECT_ID || "";
|
|
124
|
+
if (!apiKey) {
|
|
125
|
+
throw new Error("@uptrade/seo: UPTRADE_API_KEY environment variable is required for server-side SEO functions");
|
|
126
|
+
}
|
|
127
|
+
return { apiUrl, apiKey, projectId };
|
|
128
|
+
}
|
|
129
|
+
async function secureApiPost(endpoint, body = {}) {
|
|
130
|
+
const { apiUrl, apiKey } = getSecureApiConfig();
|
|
131
|
+
try {
|
|
132
|
+
const response = await fetch(`${apiUrl}${endpoint}`, {
|
|
133
|
+
method: "POST",
|
|
134
|
+
headers: {
|
|
135
|
+
"Content-Type": "application/json",
|
|
136
|
+
"x-api-key": apiKey
|
|
137
|
+
},
|
|
138
|
+
body: JSON.stringify(body),
|
|
139
|
+
next: { revalidate: 60 }
|
|
140
|
+
// Cache for 60 seconds
|
|
141
|
+
});
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
console.error(`@uptrade/seo: API error ${response.status}: ${response.statusText}`);
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
return await response.json();
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error("@uptrade/seo: Network error:", error);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
var getSEOPageData2 = cache(async (projectId, path) => {
|
|
153
|
+
const result = await secureApiPost("/api/public/seo/page", {
|
|
154
|
+
projectId,
|
|
155
|
+
path
|
|
156
|
+
});
|
|
157
|
+
return result?.page || null;
|
|
158
|
+
});
|
|
159
|
+
var getSchemaMarkups2 = cache(async (projectId, path, options) => {
|
|
160
|
+
const result = await secureApiPost("/api/public/seo/schemas", {
|
|
161
|
+
projectId,
|
|
162
|
+
path,
|
|
163
|
+
includeTypes: options?.includeTypes,
|
|
164
|
+
excludeTypes: options?.excludeTypes
|
|
165
|
+
});
|
|
166
|
+
return result?.schemas || [];
|
|
167
|
+
});
|
|
168
|
+
var getFAQData2 = cache(async (projectId, path) => {
|
|
169
|
+
const result = await secureApiPost("/api/public/seo/faq", {
|
|
170
|
+
projectId,
|
|
171
|
+
path
|
|
172
|
+
});
|
|
173
|
+
return result?.faq || null;
|
|
174
|
+
});
|
|
175
|
+
var getInternalLinks2 = cache(async (projectId, sourcePath, options) => {
|
|
176
|
+
const result = await secureApiPost("/api/public/seo/internal-links", {
|
|
177
|
+
projectId,
|
|
178
|
+
sourcePath,
|
|
179
|
+
position: options?.position,
|
|
180
|
+
limit: options?.limit
|
|
181
|
+
});
|
|
182
|
+
return result?.links || [];
|
|
183
|
+
});
|
|
184
|
+
var getContentBlock2 = cache(async (projectId, path, section) => {
|
|
185
|
+
const result = await secureApiPost("/api/public/seo/content", {
|
|
186
|
+
projectId,
|
|
187
|
+
path,
|
|
188
|
+
section
|
|
189
|
+
});
|
|
190
|
+
return result?.content || null;
|
|
191
|
+
});
|
|
192
|
+
var getABTest2 = cache(async (projectId, path, field) => {
|
|
193
|
+
const result = await secureApiPost("/api/public/seo/ab-test", {
|
|
194
|
+
projectId,
|
|
195
|
+
path,
|
|
196
|
+
field
|
|
197
|
+
});
|
|
198
|
+
return result?.test || null;
|
|
199
|
+
});
|
|
200
|
+
async function recordABImpression2(testId, variant, sessionId) {
|
|
201
|
+
await secureApiPost("/api/public/seo/ab-impression", { testId, variant, sessionId });
|
|
202
|
+
}
|
|
203
|
+
var getRedirectData = cache(async (projectId, path) => {
|
|
204
|
+
const result = await secureApiPost("/api/public/seo/redirect", {
|
|
205
|
+
projectId,
|
|
206
|
+
path
|
|
207
|
+
});
|
|
208
|
+
return result?.redirect || null;
|
|
209
|
+
});
|
|
210
|
+
var getManagedScripts2 = cache(async (projectId, position, currentPath) => {
|
|
211
|
+
const result = await secureApiPost("/api/public/seo/scripts", {
|
|
212
|
+
projectId,
|
|
213
|
+
position,
|
|
214
|
+
currentPath
|
|
215
|
+
});
|
|
216
|
+
return result?.scripts || [];
|
|
217
|
+
});
|
|
218
|
+
var getRobotsData = cache(async (projectId, path) => {
|
|
219
|
+
const result = await secureApiPost("/api/public/seo/page", {
|
|
220
|
+
projectId,
|
|
221
|
+
path
|
|
222
|
+
});
|
|
223
|
+
return result?.page?.managed_robots || null;
|
|
224
|
+
});
|
|
225
|
+
var getSitemapEntries = cache(async (projectId, options) => {
|
|
226
|
+
const result = await secureApiPost("/api/public/seo/sitemap", {
|
|
227
|
+
projectId,
|
|
228
|
+
publishedOnly: options?.publishedOnly
|
|
229
|
+
});
|
|
230
|
+
return result?.entries || [];
|
|
231
|
+
});
|
|
232
|
+
async function registerSitemap(entries) {
|
|
233
|
+
const { apiUrl, apiKey, projectId } = getSecureApiConfig();
|
|
234
|
+
try {
|
|
235
|
+
const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {
|
|
236
|
+
method: "POST",
|
|
237
|
+
headers: {
|
|
238
|
+
"Content-Type": "application/json",
|
|
239
|
+
"x-api-key": apiKey
|
|
240
|
+
},
|
|
241
|
+
body: JSON.stringify({ projectId, entries })
|
|
242
|
+
});
|
|
243
|
+
if (!response.ok) {
|
|
244
|
+
console.error(`@uptrade/seo: Sitemap registration failed: ${response.statusText}`);
|
|
245
|
+
return { success: false, created: 0, updated: 0 };
|
|
246
|
+
}
|
|
247
|
+
return await response.json();
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.error("@uptrade/seo: Sitemap registration error:", error);
|
|
250
|
+
return { success: false, created: 0, updated: 0 };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function getSignalApiConfig() {
|
|
254
|
+
const apiUrl = process.env.SIGNAL_API_URL || process.env.NEXT_PUBLIC_SIGNAL_API_URL || "https://signal.uptrademedia.com";
|
|
255
|
+
const apiKey = process.env.UPTRADE_API_KEY || "";
|
|
256
|
+
return { apiUrl, apiKey };
|
|
257
|
+
}
|
|
258
|
+
async function signalApiGet(endpoint) {
|
|
259
|
+
const { apiUrl, apiKey } = getSignalApiConfig();
|
|
260
|
+
if (!apiKey) {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
const response = await fetch(`${apiUrl}${endpoint}`, {
|
|
265
|
+
method: "GET",
|
|
266
|
+
headers: {
|
|
267
|
+
"Content-Type": "application/json",
|
|
268
|
+
"x-api-key": apiKey
|
|
269
|
+
},
|
|
270
|
+
next: { revalidate: 300 }
|
|
271
|
+
// Cache for 5 minutes
|
|
272
|
+
});
|
|
273
|
+
if (!response.ok) {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
const result = await response.json();
|
|
277
|
+
return result?.data || result;
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error("@uptrade/seo: Signal API error:", error);
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
var getEntities2 = cache(async (projectId, options) => {
|
|
284
|
+
let endpoint = `/skills/seo/entities/${projectId}`;
|
|
285
|
+
if (options?.type) {
|
|
286
|
+
endpoint += `?type=${options.type}`;
|
|
287
|
+
}
|
|
288
|
+
const result = await signalApiGet(endpoint);
|
|
289
|
+
return result || [];
|
|
290
|
+
});
|
|
291
|
+
var getPrimaryEntity = cache(async (projectId) => {
|
|
292
|
+
return signalApiGet(`/skills/seo/entities/${projectId}/primary`);
|
|
293
|
+
});
|
|
294
|
+
var getEntityEnhancedSchema2 = cache(async (projectId, pagePath) => {
|
|
295
|
+
const result = await signalApiGet(
|
|
296
|
+
`/skills/seo/schema/${projectId}/entity-enhanced?pagePath=${encodeURIComponent(pagePath)}`
|
|
297
|
+
);
|
|
298
|
+
return result?.schemas || [];
|
|
299
|
+
});
|
|
300
|
+
var getVisibilityScore = cache(async (projectId, pagePath) => {
|
|
301
|
+
const result = await signalApiGet(`/skills/seo/visibility/${projectId}`);
|
|
302
|
+
if (!result) return null;
|
|
303
|
+
return result.find((s) => s.page_path === pagePath) || null;
|
|
304
|
+
});
|
|
305
|
+
var getVisibilitySummary = cache(async (projectId) => {
|
|
306
|
+
return signalApiGet(`/skills/seo/visibility/${projectId}/summary`);
|
|
307
|
+
});
|
|
308
|
+
var DEFAULT_SPEAKABLE_SELECTORS = [
|
|
309
|
+
"h1",
|
|
310
|
+
'[data-speakable="true"]',
|
|
311
|
+
".page-summary",
|
|
312
|
+
".key-points",
|
|
313
|
+
'.aeo-block[data-speakable="true"]'
|
|
314
|
+
];
|
|
118
315
|
async function ManagedSchema({
|
|
119
316
|
projectId,
|
|
120
317
|
path,
|
|
121
318
|
additionalSchemas = [],
|
|
122
319
|
includeTypes,
|
|
123
|
-
excludeTypes
|
|
320
|
+
excludeTypes,
|
|
321
|
+
speakable,
|
|
322
|
+
pageType = "WebPage",
|
|
323
|
+
pageName,
|
|
324
|
+
pageUrl,
|
|
325
|
+
includeEntityGraph = false
|
|
124
326
|
}) {
|
|
125
327
|
const schemas = await getSchemaMarkups(projectId, path, {
|
|
126
328
|
includeTypes,
|
|
127
329
|
excludeTypes
|
|
128
330
|
});
|
|
331
|
+
let entitySchemas = [];
|
|
332
|
+
if (includeEntityGraph) {
|
|
333
|
+
entitySchemas = await getEntityEnhancedSchema(projectId, path);
|
|
334
|
+
}
|
|
129
335
|
const allSchemas = [
|
|
336
|
+
...entitySchemas,
|
|
130
337
|
...schemas.map((s) => s.schema_json),
|
|
131
338
|
...additionalSchemas
|
|
132
339
|
];
|
|
340
|
+
if (speakable && pageName && pageUrl) {
|
|
341
|
+
const speakableSchema = createSpeakableWebPageSchema(
|
|
342
|
+
pageType,
|
|
343
|
+
pageName,
|
|
344
|
+
pageUrl,
|
|
345
|
+
typeof speakable === "object" ? speakable : void 0
|
|
346
|
+
);
|
|
347
|
+
allSchemas.push(speakableSchema);
|
|
348
|
+
}
|
|
133
349
|
if (allSchemas.length === 0) {
|
|
134
350
|
return null;
|
|
135
351
|
}
|
|
@@ -158,6 +374,25 @@ function createSchema(type, data) {
|
|
|
158
374
|
...data
|
|
159
375
|
};
|
|
160
376
|
}
|
|
377
|
+
function createSpeakableWebPageSchema(type, name, url, speakable) {
|
|
378
|
+
const speakableSpec = {
|
|
379
|
+
"@type": "SpeakableSpecification"
|
|
380
|
+
};
|
|
381
|
+
if (speakable?.cssSelector?.length) {
|
|
382
|
+
speakableSpec.cssSelector = speakable.cssSelector;
|
|
383
|
+
} else if (speakable?.xpath?.length) {
|
|
384
|
+
speakableSpec.xpath = speakable.xpath;
|
|
385
|
+
} else {
|
|
386
|
+
speakableSpec.cssSelector = DEFAULT_SPEAKABLE_SELECTORS;
|
|
387
|
+
}
|
|
388
|
+
return {
|
|
389
|
+
"@context": "https://schema.org",
|
|
390
|
+
"@type": type,
|
|
391
|
+
name,
|
|
392
|
+
url,
|
|
393
|
+
speakable: speakableSpec
|
|
394
|
+
};
|
|
395
|
+
}
|
|
161
396
|
function createBreadcrumbSchema(baseUrl, path, labels) {
|
|
162
397
|
const segments = path.split("/").filter(Boolean);
|
|
163
398
|
const items = segments.map((segment, index) => {
|
|
@@ -297,13 +532,46 @@ async function ManagedInternalLinks({
|
|
|
297
532
|
function renderMarkdown(content) {
|
|
298
533
|
return content.replace(/^### (.*$)/gim, "<h3>$1</h3>").replace(/^## (.*$)/gim, "<h2>$1</h2>").replace(/^# (.*$)/gim, "<h1>$1</h1>").replace(/\*\*(.*)\*\*/gim, "<strong>$1</strong>").replace(/\*(.*)\*/gim, "<em>$1</em>").replace(/\[(.*?)\]\((.*?)\)/gim, '<a href="$2">$1</a>').replace(/\n\n/gim, "</p><p>").replace(/^(.+)$/gim, "<p>$1</p>");
|
|
299
534
|
}
|
|
535
|
+
function injectEntityAnnotations(html, entities) {
|
|
536
|
+
if (!entities.length) return html;
|
|
537
|
+
let annotatedHtml = html;
|
|
538
|
+
const sortedEntities = [...entities].sort((a, b) => b.name.length - a.name.length);
|
|
539
|
+
for (const entity of sortedEntities) {
|
|
540
|
+
if (entity.name.length < 3) continue;
|
|
541
|
+
const regex = new RegExp(
|
|
542
|
+
`(?<![\\w-])(?<!data-sonor-entity=")${escapeRegExp(entity.name)}(?![\\w-])`,
|
|
543
|
+
"gi"
|
|
544
|
+
);
|
|
545
|
+
const schemaType = getSchemaTypeForEntity(entity.entity_type);
|
|
546
|
+
annotatedHtml = annotatedHtml.replace(regex, (match) => {
|
|
547
|
+
return `<span class="aeo-entity aeo-entity-${entity.entity_type}" data-sonor-entity="${entity.id}" data-sonor-entity-type="${entity.entity_type}" data-sonor-entity-name="${entity.name}" itemscope itemtype="https://schema.org/${schemaType}"><span itemprop="name">${match}</span></span>`;
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
return annotatedHtml;
|
|
551
|
+
}
|
|
552
|
+
function escapeRegExp(string) {
|
|
553
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
554
|
+
}
|
|
555
|
+
function getSchemaTypeForEntity(entityType) {
|
|
556
|
+
const typeMap = {
|
|
557
|
+
organization: "Organization",
|
|
558
|
+
person: "Person",
|
|
559
|
+
service: "Service",
|
|
560
|
+
product: "Product",
|
|
561
|
+
location: "Place",
|
|
562
|
+
concept: "Thing",
|
|
563
|
+
credential: "EducationalOccupationalCredential"
|
|
564
|
+
};
|
|
565
|
+
return typeMap[entityType] || "Thing";
|
|
566
|
+
}
|
|
300
567
|
async function ManagedContent({
|
|
301
568
|
projectId,
|
|
302
569
|
path,
|
|
303
570
|
section,
|
|
304
571
|
fallback,
|
|
305
572
|
className,
|
|
306
|
-
components = {}
|
|
573
|
+
components = {},
|
|
574
|
+
injectEntityAnnotations: shouldInjectEntities = false
|
|
307
575
|
}) {
|
|
308
576
|
const block = await getContentBlock(projectId, path, section);
|
|
309
577
|
if (!block) {
|
|
@@ -312,18 +580,32 @@ async function ManagedContent({
|
|
|
312
580
|
}
|
|
313
581
|
return null;
|
|
314
582
|
}
|
|
583
|
+
let entities = [];
|
|
584
|
+
if (shouldInjectEntities) {
|
|
585
|
+
try {
|
|
586
|
+
entities = await getEntities(projectId);
|
|
587
|
+
} catch (err) {
|
|
588
|
+
console.warn("@uptrade/seo: Failed to fetch entities for annotation:", err);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
315
591
|
const containerClass = className || `uptrade-content uptrade-content--${section}`;
|
|
592
|
+
const processHtml = (html) => {
|
|
593
|
+
if (shouldInjectEntities && entities.length > 0) {
|
|
594
|
+
return injectEntityAnnotations(html, entities);
|
|
595
|
+
}
|
|
596
|
+
return html;
|
|
597
|
+
};
|
|
316
598
|
switch (block.content_type) {
|
|
317
599
|
case "html":
|
|
318
600
|
return /* @__PURE__ */ jsx(
|
|
319
601
|
"div",
|
|
320
602
|
{
|
|
321
603
|
className: containerClass,
|
|
322
|
-
dangerouslySetInnerHTML: { __html: block.content }
|
|
604
|
+
dangerouslySetInnerHTML: { __html: processHtml(block.content) }
|
|
323
605
|
}
|
|
324
606
|
);
|
|
325
607
|
case "markdown":
|
|
326
|
-
const htmlContent = renderMarkdown(block.content);
|
|
608
|
+
const htmlContent = processHtml(renderMarkdown(block.content));
|
|
327
609
|
return /* @__PURE__ */ jsx(
|
|
328
610
|
"div",
|
|
329
611
|
{
|
|
@@ -405,7 +687,114 @@ async function ManagedNoScripts({
|
|
|
405
687
|
}
|
|
406
688
|
return /* @__PURE__ */ jsx("noscript", { dangerouslySetInnerHTML: { __html: noscriptContent } });
|
|
407
689
|
}
|
|
690
|
+
function getApiConfig() {
|
|
691
|
+
const apiUrl = process.env.UPTRADE_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL || "https://api.uptrademedia.com";
|
|
692
|
+
return { apiUrl };
|
|
693
|
+
}
|
|
694
|
+
var getLocationSection = cache(async (projectId, path, section) => {
|
|
695
|
+
const { apiUrl } = getApiConfig();
|
|
696
|
+
try {
|
|
697
|
+
const response = await fetch(`${apiUrl}/api/public/seo/location-content`, {
|
|
698
|
+
method: "POST",
|
|
699
|
+
headers: { "Content-Type": "application/json" },
|
|
700
|
+
body: JSON.stringify({
|
|
701
|
+
project_id: projectId,
|
|
702
|
+
path,
|
|
703
|
+
section
|
|
704
|
+
}),
|
|
705
|
+
next: { revalidate: 3600 }
|
|
706
|
+
// Cache for 1 hour
|
|
707
|
+
});
|
|
708
|
+
if (!response.ok) {
|
|
709
|
+
console.error(`LocationPageContent: Failed to fetch section "${section}" for path "${path}"`);
|
|
710
|
+
return null;
|
|
711
|
+
}
|
|
712
|
+
const data = await response.json();
|
|
713
|
+
return data;
|
|
714
|
+
} catch (error) {
|
|
715
|
+
console.error("LocationPageContent: API error:", error);
|
|
716
|
+
return null;
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
function HeroRenderer({ data, className }) {
|
|
720
|
+
return /* @__PURE__ */ jsxs("section", { className: className || "location-hero", children: [
|
|
721
|
+
/* @__PURE__ */ jsx("h1", { children: data.title }),
|
|
722
|
+
data.subtitle && /* @__PURE__ */ jsx("p", { className: "subtitle", children: data.subtitle }),
|
|
723
|
+
data.stats && /* @__PURE__ */ jsx("div", { className: "stats-grid", children: data.stats.map((stat, i) => /* @__PURE__ */ jsxs("div", { className: "stat", children: [
|
|
724
|
+
/* @__PURE__ */ jsx("span", { className: "stat-value", children: stat.value }),
|
|
725
|
+
/* @__PURE__ */ jsx("span", { className: "stat-label", children: stat.label })
|
|
726
|
+
] }, i)) }),
|
|
727
|
+
data.cta_text && data.cta_href && /* @__PURE__ */ jsx("a", { href: data.cta_href, className: "cta-button", children: data.cta_text })
|
|
728
|
+
] });
|
|
729
|
+
}
|
|
730
|
+
function TextRenderer({ data, className }) {
|
|
731
|
+
if (data.html) {
|
|
732
|
+
return /* @__PURE__ */ jsx(
|
|
733
|
+
"section",
|
|
734
|
+
{
|
|
735
|
+
className: className || "location-text",
|
|
736
|
+
dangerouslySetInnerHTML: { __html: data.html }
|
|
737
|
+
}
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
return /* @__PURE__ */ jsxs("section", { className: className || "location-text", children: [
|
|
741
|
+
data.heading && /* @__PURE__ */ jsx("h2", { children: data.heading }),
|
|
742
|
+
data.paragraphs.map((p, i) => /* @__PURE__ */ jsx("p", { children: p }, i))
|
|
743
|
+
] });
|
|
744
|
+
}
|
|
745
|
+
function ServicesGridRenderer({ data, className }) {
|
|
746
|
+
return /* @__PURE__ */ jsx("section", { className: className || "location-services-grid", children: /* @__PURE__ */ jsx("div", { className: "services-list", children: data.services.map((service, i) => /* @__PURE__ */ jsxs("a", { href: service.href, className: "service-card", children: [
|
|
747
|
+
service.icon && /* @__PURE__ */ jsx("span", { className: "service-icon", children: service.icon }),
|
|
748
|
+
/* @__PURE__ */ jsx("h3", { children: service.title }),
|
|
749
|
+
/* @__PURE__ */ jsx("p", { children: service.description })
|
|
750
|
+
] }, i)) }) });
|
|
751
|
+
}
|
|
752
|
+
function DefaultRenderer({ data, className }) {
|
|
753
|
+
if (process.env.NODE_ENV === "development") {
|
|
754
|
+
return /* @__PURE__ */ jsx("section", { className, children: /* @__PURE__ */ jsx("pre", { style: { fontSize: "12px", background: "#f0f0f0", padding: "1rem" }, children: JSON.stringify(data, null, 2) }) });
|
|
755
|
+
}
|
|
756
|
+
if (typeof data.content === "string") {
|
|
757
|
+
return /* @__PURE__ */ jsx(
|
|
758
|
+
"section",
|
|
759
|
+
{
|
|
760
|
+
className,
|
|
761
|
+
dangerouslySetInnerHTML: { __html: data.content }
|
|
762
|
+
}
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
return null;
|
|
766
|
+
}
|
|
767
|
+
async function LocationPageContent({
|
|
768
|
+
projectId,
|
|
769
|
+
path,
|
|
770
|
+
section,
|
|
771
|
+
fallback = null,
|
|
772
|
+
className,
|
|
773
|
+
render
|
|
774
|
+
}) {
|
|
775
|
+
const data = await getLocationSection(projectId, path, section);
|
|
776
|
+
if (!data) {
|
|
777
|
+
return fallback;
|
|
778
|
+
}
|
|
779
|
+
if (render) {
|
|
780
|
+
return /* @__PURE__ */ jsx(Fragment, { children: render(data) });
|
|
781
|
+
}
|
|
782
|
+
switch (data.type) {
|
|
783
|
+
case "hero":
|
|
784
|
+
return /* @__PURE__ */ jsx(HeroRenderer, { data: data.content, className });
|
|
785
|
+
case "text":
|
|
786
|
+
case "intro":
|
|
787
|
+
case "about":
|
|
788
|
+
case "about_location":
|
|
789
|
+
return /* @__PURE__ */ jsx(TextRenderer, { data: data.content, className });
|
|
790
|
+
case "services_grid":
|
|
791
|
+
case "services":
|
|
792
|
+
return /* @__PURE__ */ jsx(ServicesGridRenderer, { data: data.content, className });
|
|
793
|
+
default:
|
|
794
|
+
return /* @__PURE__ */ jsx(DefaultRenderer, { data, className });
|
|
795
|
+
}
|
|
796
|
+
}
|
|
408
797
|
|
|
409
|
-
export { ManagedContent, ManagedFAQ, ManagedInternalLinks, ManagedNoScripts, ManagedSchema, ManagedScripts, createBreadcrumbSchema, createSchema, ManagedSchema as default, getABVariant, getManagedContentData, getManagedMetadata, getManagedMetadataWithAB };
|
|
798
|
+
export { LocationPageContent, ManagedContent, ManagedFAQ, ManagedInternalLinks, ManagedNoScripts, ManagedSchema, ManagedScripts, createBreadcrumbSchema, createSchema, ManagedSchema as default, getABTest2 as getABTest, getABVariant, getContentBlock2 as getContentBlock, getEntities2 as getEntities, getEntityEnhancedSchema2 as getEntityEnhancedSchema, getFAQData2 as getFAQData, getInternalLinks2 as getInternalLinks, getLocationSection, getManagedContentData, getManagedMetadata, getManagedMetadataWithAB, getManagedScripts2 as getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData2 as getSEOPageData, getSchemaMarkups2 as getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression2 as recordABImpression, registerSitemap };
|
|
410
799
|
//# sourceMappingURL=index.mjs.map
|
|
411
800
|
//# sourceMappingURL=index.mjs.map
|