@uptrademedia/site-kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +305 -0
  2. package/dist/analytics/index.js +88 -0
  3. package/dist/analytics/index.js.map +1 -0
  4. package/dist/analytics/index.mjs +70 -0
  5. package/dist/analytics/index.mjs.map +1 -0
  6. package/dist/api-N35S3EES.js +57 -0
  7. package/dist/api-N35S3EES.js.map +1 -0
  8. package/dist/api-SYBTK7Z7.mjs +4 -0
  9. package/dist/api-SYBTK7Z7.mjs.map +1 -0
  10. package/dist/blog/index.js +200 -0
  11. package/dist/blog/index.js.map +1 -0
  12. package/dist/blog/index.mjs +194 -0
  13. package/dist/blog/index.mjs.map +1 -0
  14. package/dist/chunk-3MUOUXHV.js +3721 -0
  15. package/dist/chunk-3MUOUXHV.js.map +1 -0
  16. package/dist/chunk-4HVYXYQL 2.mjs +255 -0
  17. package/dist/chunk-4HVYXYQL.mjs +255 -0
  18. package/dist/chunk-4HVYXYQL.mjs.map +1 -0
  19. package/dist/chunk-7H6I3ECV.mjs +120 -0
  20. package/dist/chunk-7H6I3ECV.mjs.map +1 -0
  21. package/dist/chunk-COI6GOX2.mjs +3679 -0
  22. package/dist/chunk-COI6GOX2.mjs.map +1 -0
  23. package/dist/chunk-EQCVQC35.js +35 -0
  24. package/dist/chunk-EQCVQC35.js 2.map +1 -0
  25. package/dist/chunk-EQCVQC35.js.map +1 -0
  26. package/dist/chunk-FEBYQGY4 2.mjs +251 -0
  27. package/dist/chunk-FEBYQGY4.mjs +251 -0
  28. package/dist/chunk-FEBYQGY4.mjs.map +1 -0
  29. package/dist/chunk-FKVJOT2F.mjs +796 -0
  30. package/dist/chunk-FKVJOT2F.mjs.map +1 -0
  31. package/dist/chunk-GQ6ZOU2N.mjs +134 -0
  32. package/dist/chunk-GQ6ZOU2N.mjs.map +1 -0
  33. package/dist/chunk-HCFPU7TU.js +137 -0
  34. package/dist/chunk-HCFPU7TU.js.map +1 -0
  35. package/dist/chunk-NYKRE2FL 2.mjs +31 -0
  36. package/dist/chunk-NYKRE2FL.mjs +31 -0
  37. package/dist/chunk-NYKRE2FL.mjs 2.map +1 -0
  38. package/dist/chunk-NYKRE2FL.mjs.map +1 -0
  39. package/dist/chunk-QP5NCO2E.js +133 -0
  40. package/dist/chunk-QP5NCO2E.js.map +1 -0
  41. package/dist/chunk-RV7H3I6J.js +255 -0
  42. package/dist/chunk-RV7H3I6J.js 2.map +1 -0
  43. package/dist/chunk-RV7H3I6J.js.map +1 -0
  44. package/dist/chunk-SBVEYCSV.js +140 -0
  45. package/dist/chunk-SBVEYCSV.js.map +1 -0
  46. package/dist/chunk-TUKGA3UK.js +257 -0
  47. package/dist/chunk-TUKGA3UK.js 2.map +1 -0
  48. package/dist/chunk-TUKGA3UK.js.map +1 -0
  49. package/dist/chunk-V3F5J6CV.js +801 -0
  50. package/dist/chunk-V3F5J6CV.js.map +1 -0
  51. package/dist/chunk-WPSRS352.mjs +135 -0
  52. package/dist/chunk-WPSRS352.mjs.map +1 -0
  53. package/dist/commerce/index.js +157 -0
  54. package/dist/commerce/index.js.map +1 -0
  55. package/dist/commerce/index.mjs +4 -0
  56. package/dist/commerce/index.mjs.map +1 -0
  57. package/dist/commerce/server.js +186 -0
  58. package/dist/commerce/server.js.map +1 -0
  59. package/dist/commerce/server.mjs +176 -0
  60. package/dist/commerce/server.mjs.map +1 -0
  61. package/dist/engage/index.js +50 -0
  62. package/dist/engage/index.js.map +1 -0
  63. package/dist/engage/index.mjs +44 -0
  64. package/dist/engage/index.mjs.map +1 -0
  65. package/dist/forms/index.js +1053 -0
  66. package/dist/forms/index.js.map +1 -0
  67. package/dist/forms/index.mjs +1035 -0
  68. package/dist/forms/index.mjs.map +1 -0
  69. package/dist/generators-7Y5ABRYV 2.mjs +161 -0
  70. package/dist/generators-7Y5ABRYV.mjs +161 -0
  71. package/dist/generators-7Y5ABRYV.mjs 2.map +1 -0
  72. package/dist/generators-7Y5ABRYV.mjs.map +1 -0
  73. package/dist/generators-GWIYCA5M.js +171 -0
  74. package/dist/generators-GWIYCA5M.js 2.map +1 -0
  75. package/dist/generators-GWIYCA5M.js.map +1 -0
  76. package/dist/index 2.mjs +74 -0
  77. package/dist/index.js +326 -0
  78. package/dist/index.js 2.map +1 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/index.mjs +222 -0
  81. package/dist/index.mjs.map +1 -0
  82. package/dist/migrator-V6KS75EA 2.mjs +265 -0
  83. package/dist/migrator-V6KS75EA.mjs +265 -0
  84. package/dist/migrator-V6KS75EA.mjs 2.map +1 -0
  85. package/dist/migrator-V6KS75EA.mjs.map +1 -0
  86. package/dist/migrator-XKM7YQCY.js +272 -0
  87. package/dist/migrator-XKM7YQCY.js 2.map +1 -0
  88. package/dist/migrator-XKM7YQCY.js.map +1 -0
  89. package/dist/scanner-MF7P3CDE 2.mjs +14386 -0
  90. package/dist/scanner-MF7P3CDE.mjs +14386 -0
  91. package/dist/scanner-MF7P3CDE.mjs 2.map +1 -0
  92. package/dist/scanner-MF7P3CDE.mjs.map +1 -0
  93. package/dist/scanner-NT6YG4TD 2.js +14397 -0
  94. package/dist/scanner-NT6YG4TD.js +14397 -0
  95. package/dist/scanner-NT6YG4TD.js 2.map +1 -0
  96. package/dist/scanner-NT6YG4TD.js.map +1 -0
  97. package/dist/seo/index.js +447 -0
  98. package/dist/seo/index.js.map +1 -0
  99. package/dist/seo/index.mjs +411 -0
  100. package/dist/seo/index.mjs.map +1 -0
  101. package/dist/seo/server.js +66 -0
  102. package/dist/seo/server.js.map +1 -0
  103. package/dist/seo/server.mjs +5 -0
  104. package/dist/seo/server.mjs.map +1 -0
  105. package/dist/setup/index.js +1050 -0
  106. package/dist/setup/index.js.map +1 -0
  107. package/dist/setup/index.mjs +1046 -0
  108. package/dist/setup/index.mjs.map +1 -0
  109. package/dist/sitemap/index.js +212 -0
  110. package/dist/sitemap/index.js.map +1 -0
  111. package/dist/sitemap/index.mjs +206 -0
  112. package/dist/sitemap/index.mjs.map +1 -0
  113. package/dist/web-vitals-BH55V7EJ.js +252 -0
  114. package/dist/web-vitals-BH55V7EJ.js 2.map +1 -0
  115. package/dist/web-vitals-BH55V7EJ.js.map +1 -0
  116. package/dist/web-vitals-RJYPWAR3 2.mjs +241 -0
  117. package/dist/web-vitals-RJYPWAR3.mjs +241 -0
  118. package/dist/web-vitals-RJYPWAR3.mjs 2.map +1 -0
  119. package/dist/web-vitals-RJYPWAR3.mjs.map +1 -0
  120. package/package.json +118 -0
@@ -0,0 +1,447 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var chunkHCFPU7TU_js = require('../chunk-HCFPU7TU.js');
6
+ var chunkSBVEYCSV_js = require('../chunk-SBVEYCSV.js');
7
+ var chunkQP5NCO2E_js = require('../chunk-QP5NCO2E.js');
8
+ require('../chunk-EQCVQC35.js');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+
11
+ // src/seo/getManagedMetadata.ts
12
+ async function getManagedMetadata(options) {
13
+ const { projectId, path, fallback = {}, overrides = {} } = options;
14
+ const pageData = await chunkQP5NCO2E_js.getSEOPageData(projectId, path);
15
+ if (!pageData) {
16
+ return {
17
+ ...fallback,
18
+ ...overrides,
19
+ _managed: false,
20
+ _source: "fallback"
21
+ };
22
+ }
23
+ const metadata = {
24
+ _managed: true,
25
+ _source: "database"
26
+ };
27
+ if (pageData.managed_title) {
28
+ metadata.title = pageData.managed_title;
29
+ } else if (fallback.title) {
30
+ metadata.title = fallback.title;
31
+ }
32
+ if (pageData.managed_description) {
33
+ metadata.description = pageData.managed_description;
34
+ } else if (fallback.description) {
35
+ metadata.description = fallback.description;
36
+ }
37
+ if (pageData.managed_keywords?.length) {
38
+ metadata.keywords = pageData.managed_keywords;
39
+ } else if (fallback.keywords) {
40
+ metadata.keywords = fallback.keywords;
41
+ }
42
+ if (pageData.managed_robots) {
43
+ metadata.robots = pageData.managed_robots;
44
+ }
45
+ if (pageData.managed_canonical) {
46
+ metadata.alternates = {
47
+ ...metadata.alternates,
48
+ canonical: pageData.managed_canonical
49
+ };
50
+ }
51
+ const ogTitle = pageData.managed_og_title || pageData.managed_title;
52
+ const ogDescription = pageData.managed_og_description || pageData.managed_description;
53
+ const ogImage = pageData.managed_og_image;
54
+ if (ogTitle || ogDescription || ogImage) {
55
+ metadata.openGraph = {
56
+ ...ogTitle && { title: ogTitle },
57
+ ...ogDescription && { description: ogDescription },
58
+ ...ogImage && { images: [{ url: ogImage }] }
59
+ };
60
+ }
61
+ if (ogTitle || ogDescription || ogImage) {
62
+ metadata.twitter = {
63
+ card: "summary_large_image",
64
+ ...ogTitle && { title: ogTitle },
65
+ ...ogDescription && { description: ogDescription },
66
+ ...ogImage && { images: [ogImage] }
67
+ };
68
+ }
69
+ return {
70
+ ...metadata,
71
+ ...overrides,
72
+ _managed: true,
73
+ _source: "database"
74
+ };
75
+ }
76
+ async function getABVariant(options) {
77
+ const { projectId, path, field, sessionId } = options;
78
+ const test = await chunkQP5NCO2E_js.getABTest(projectId, path, field);
79
+ if (!test) {
80
+ return null;
81
+ }
82
+ let variant;
83
+ if (sessionId) {
84
+ const hash = sessionId.split("").reduce((acc, char) => {
85
+ return (acc << 5) - acc + char.charCodeAt(0);
86
+ }, 0);
87
+ variant = Math.abs(hash) % 100 < test.traffic_split * 100 ? "a" : "b";
88
+ } else {
89
+ variant = Math.random() < test.traffic_split ? "a" : "b";
90
+ }
91
+ chunkQP5NCO2E_js.recordABImpression(test.id, variant, sessionId).catch(() => {
92
+ });
93
+ return {
94
+ testId: test.id,
95
+ variant,
96
+ value: variant === "a" ? test.variant_a : test.variant_b
97
+ };
98
+ }
99
+ async function getManagedMetadataWithAB(options) {
100
+ const { sessionId, ...metadataOptions } = options;
101
+ const metadata = await getManagedMetadata(metadataOptions);
102
+ const titleTest = await getABVariant({
103
+ projectId: options.projectId,
104
+ path: options.path,
105
+ field: "title",
106
+ sessionId
107
+ });
108
+ if (titleTest) {
109
+ metadata.title = titleTest.value;
110
+ }
111
+ const descTest = await getABVariant({
112
+ projectId: options.projectId,
113
+ path: options.path,
114
+ field: "description",
115
+ sessionId
116
+ });
117
+ if (descTest) {
118
+ metadata.description = descTest.value;
119
+ }
120
+ return metadata;
121
+ }
122
+ async function ManagedSchema({
123
+ projectId,
124
+ path,
125
+ additionalSchemas = [],
126
+ includeTypes,
127
+ excludeTypes
128
+ }) {
129
+ const schemas = await chunkQP5NCO2E_js.getSchemaMarkups(projectId, path, {
130
+ includeTypes,
131
+ excludeTypes
132
+ });
133
+ const allSchemas = [
134
+ ...schemas.map((s) => s.schema_json),
135
+ ...additionalSchemas
136
+ ];
137
+ if (allSchemas.length === 0) {
138
+ return null;
139
+ }
140
+ const schemaContent = allSchemas.length === 1 ? allSchemas[0] : {
141
+ "@context": "https://schema.org",
142
+ "@graph": allSchemas.map((s) => {
143
+ const { "@context": _, ...rest } = s;
144
+ return rest;
145
+ })
146
+ };
147
+ const finalSchema = allSchemas.length === 1 ? { "@context": "https://schema.org", ...schemaContent } : schemaContent;
148
+ return /* @__PURE__ */ jsxRuntime.jsx(
149
+ "script",
150
+ {
151
+ type: "application/ld+json",
152
+ dangerouslySetInnerHTML: {
153
+ __html: JSON.stringify(finalSchema, null, 0)
154
+ }
155
+ }
156
+ );
157
+ }
158
+ function createSchema(type, data) {
159
+ return {
160
+ "@context": "https://schema.org",
161
+ "@type": type,
162
+ ...data
163
+ };
164
+ }
165
+ function createBreadcrumbSchema(baseUrl, path, labels) {
166
+ const segments = path.split("/").filter(Boolean);
167
+ const items = segments.map((segment, index) => {
168
+ const itemPath = "/" + segments.slice(0, index + 1).join("/");
169
+ const label = labels?.[segment] || segment.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
170
+ return {
171
+ "@type": "ListItem",
172
+ position: index + 1,
173
+ name: label,
174
+ item: `${baseUrl}${itemPath}`
175
+ };
176
+ });
177
+ items.unshift({
178
+ "@type": "ListItem",
179
+ position: 0,
180
+ name: "Home",
181
+ item: baseUrl
182
+ });
183
+ items.forEach((item, index) => {
184
+ item.position = index + 1;
185
+ });
186
+ return createSchema("BreadcrumbList", {
187
+ itemListElement: items
188
+ });
189
+ }
190
+ function DefaultFAQItem({ item, index }) {
191
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "uptrade-faq-item", children: [
192
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "uptrade-faq-question", children: item.question }),
193
+ /* @__PURE__ */ jsxRuntime.jsx(
194
+ "div",
195
+ {
196
+ className: "uptrade-faq-answer",
197
+ dangerouslySetInnerHTML: { __html: item.answer }
198
+ }
199
+ )
200
+ ] }, item.id);
201
+ }
202
+ function generateFAQSchema(items) {
203
+ return createSchema("FAQPage", {
204
+ mainEntity: items.filter((item) => item.is_visible).map((item) => ({
205
+ "@type": "Question",
206
+ name: item.question,
207
+ acceptedAnswer: {
208
+ "@type": "Answer",
209
+ text: item.answer
210
+ }
211
+ }))
212
+ });
213
+ }
214
+ async function ManagedFAQ({
215
+ projectId,
216
+ path,
217
+ className,
218
+ renderItem,
219
+ includeSchema = true,
220
+ showTitle = true
221
+ }) {
222
+ const faqData = await chunkQP5NCO2E_js.getFAQData(projectId, path);
223
+ if (!faqData || !faqData.items?.length) {
224
+ return null;
225
+ }
226
+ const visibleItems = faqData.items.filter((item) => item.is_visible);
227
+ if (visibleItems.length === 0) {
228
+ return null;
229
+ }
230
+ visibleItems.sort((a, b) => a.order - b.order);
231
+ const shouldIncludeSchema = includeSchema && faqData.include_schema;
232
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
233
+ shouldIncludeSchema && /* @__PURE__ */ jsxRuntime.jsx(
234
+ "script",
235
+ {
236
+ type: "application/ld+json",
237
+ dangerouslySetInnerHTML: {
238
+ __html: JSON.stringify(generateFAQSchema(visibleItems), null, 0)
239
+ }
240
+ }
241
+ ),
242
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: className || "uptrade-faq", children: [
243
+ showTitle && faqData.title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "uptrade-faq-title", children: faqData.title }),
244
+ faqData.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "uptrade-faq-description", children: faqData.description }),
245
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "uptrade-faq-items", children: visibleItems.map(
246
+ (item, index) => renderItem ? renderItem(item, index) : /* @__PURE__ */ jsxRuntime.jsx(DefaultFAQItem, { item, index }, item.id)
247
+ ) })
248
+ ] })
249
+ ] });
250
+ }
251
+ function DefaultLinkRenderer({ link }) {
252
+ const href = link.target_url || link.target_path;
253
+ return /* @__PURE__ */ jsxRuntime.jsx(
254
+ "a",
255
+ {
256
+ href,
257
+ className: "uptrade-internal-link",
258
+ children: link.anchor_text
259
+ },
260
+ link.id
261
+ );
262
+ }
263
+ async function ManagedInternalLinks({
264
+ projectId,
265
+ path,
266
+ position = "bottom",
267
+ limit = 5,
268
+ className,
269
+ renderLink
270
+ }) {
271
+ const links = await chunkQP5NCO2E_js.getInternalLinks(projectId, path, { position, limit });
272
+ if (!links.length) {
273
+ return null;
274
+ }
275
+ const containerClass = className || `uptrade-internal-links uptrade-internal-links--${position}`;
276
+ if (position === "inline") {
277
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: containerClass, children: links.map(
278
+ (link) => renderLink ? renderLink(link) : /* @__PURE__ */ jsxRuntime.jsx(DefaultLinkRenderer, { link }, link.id)
279
+ ) });
280
+ }
281
+ if (position === "sidebar") {
282
+ return /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: containerClass, children: [
283
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "uptrade-internal-links-title", children: "Related Pages" }),
284
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "uptrade-internal-links-list", children: links.map((link) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: renderLink ? renderLink(link) : /* @__PURE__ */ jsxRuntime.jsx(DefaultLinkRenderer, { link }) }, link.id)) })
285
+ ] });
286
+ }
287
+ if (position === "related") {
288
+ return /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: containerClass, "aria-label": "Related content", children: [
289
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "uptrade-internal-links-title", children: "You May Also Like" }),
290
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "uptrade-internal-links-grid", children: links.map((link) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "uptrade-internal-link-card", children: [
291
+ renderLink ? renderLink(link) : /* @__PURE__ */ jsxRuntime.jsx(DefaultLinkRenderer, { link }),
292
+ link.context && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "uptrade-internal-link-context", children: link.context })
293
+ ] }, link.id)) })
294
+ ] });
295
+ }
296
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: containerClass, children: [
297
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "uptrade-internal-links-title", children: "Related Articles" }),
298
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "uptrade-internal-links-list", children: links.map((link) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: renderLink ? renderLink(link) : /* @__PURE__ */ jsxRuntime.jsx(DefaultLinkRenderer, { link }) }, link.id)) })
299
+ ] });
300
+ }
301
+ function renderMarkdown(content) {
302
+ 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>");
303
+ }
304
+ async function ManagedContent({
305
+ projectId,
306
+ path,
307
+ section,
308
+ fallback,
309
+ className,
310
+ components = {}
311
+ }) {
312
+ const block = await chunkQP5NCO2E_js.getContentBlock(projectId, path, section);
313
+ if (!block) {
314
+ if (fallback) {
315
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback });
316
+ }
317
+ return null;
318
+ }
319
+ const containerClass = className || `uptrade-content uptrade-content--${section}`;
320
+ switch (block.content_type) {
321
+ case "html":
322
+ return /* @__PURE__ */ jsxRuntime.jsx(
323
+ "div",
324
+ {
325
+ className: containerClass,
326
+ dangerouslySetInnerHTML: { __html: block.content }
327
+ }
328
+ );
329
+ case "markdown":
330
+ const htmlContent = renderMarkdown(block.content);
331
+ return /* @__PURE__ */ jsxRuntime.jsx(
332
+ "div",
333
+ {
334
+ className: containerClass,
335
+ dangerouslySetInnerHTML: { __html: htmlContent }
336
+ }
337
+ );
338
+ case "json":
339
+ const jsonData = typeof block.content === "string" ? JSON.parse(block.content) : block.content;
340
+ return /* @__PURE__ */ jsxRuntime.jsxs(
341
+ "div",
342
+ {
343
+ className: containerClass,
344
+ "data-content": JSON.stringify(jsonData),
345
+ children: [
346
+ jsonData.title && /* @__PURE__ */ jsxRuntime.jsx("h2", { children: jsonData.title }),
347
+ jsonData.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "subtitle", children: jsonData.subtitle }),
348
+ jsonData.content && /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: jsonData.content } }),
349
+ jsonData.items && /* @__PURE__ */ jsxRuntime.jsx("ul", { children: jsonData.items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: typeof item === "string" ? item : item.text }, index)) })
350
+ ]
351
+ }
352
+ );
353
+ case "react":
354
+ const componentData = typeof block.content === "string" ? JSON.parse(block.content) : block.content;
355
+ const componentName = componentData.component;
356
+ const componentProps = componentData.props || {};
357
+ const Component = components[componentName];
358
+ if (!Component) {
359
+ console.warn(`@uptrade/seo: Component "${componentName}" not found in components map`);
360
+ return fallback ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback }) : null;
361
+ }
362
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: containerClass, children: /* @__PURE__ */ jsxRuntime.jsx(Component, { ...componentProps }) });
363
+ default:
364
+ console.warn(`@uptrade/seo: Unknown content type "${block.content_type}"`);
365
+ return fallback ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback }) : null;
366
+ }
367
+ }
368
+ async function getManagedContentData(projectId, path, section) {
369
+ return chunkQP5NCO2E_js.getContentBlock(projectId, path, section);
370
+ }
371
+ async function ManagedScripts({
372
+ projectId,
373
+ position,
374
+ path
375
+ }) {
376
+ const scripts = await chunkQP5NCO2E_js.getManagedScripts(projectId, position, path);
377
+ if (!scripts.length) {
378
+ return null;
379
+ }
380
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: scripts.map((script) => {
381
+ if (script.script_type === "external") {
382
+ const attrs = {
383
+ key: script.id,
384
+ src: script.src,
385
+ ...script.async && { async: true },
386
+ ...script.defer && { defer: true },
387
+ ...script.attributes
388
+ };
389
+ return /* @__PURE__ */ jsxRuntime.jsx("script", { ...attrs });
390
+ }
391
+ return /* @__PURE__ */ jsxRuntime.jsx(
392
+ "script",
393
+ {
394
+ dangerouslySetInnerHTML: { __html: script.content || "" },
395
+ ...script.attributes
396
+ },
397
+ script.id
398
+ );
399
+ }) });
400
+ }
401
+ async function ManagedNoScripts({
402
+ projectId,
403
+ path
404
+ }) {
405
+ const scripts = await chunkQP5NCO2E_js.getManagedScripts(projectId, "body-start", path);
406
+ const noscriptContent = scripts.filter((s) => s.attributes?.noscript).map((s) => s.attributes?.noscript).join("");
407
+ if (!noscriptContent) {
408
+ return null;
409
+ }
410
+ return /* @__PURE__ */ jsxRuntime.jsx("noscript", { dangerouslySetInnerHTML: { __html: noscriptContent } });
411
+ }
412
+
413
+ Object.defineProperty(exports, "SitemapSync", {
414
+ enumerable: true,
415
+ get: function () { return chunkHCFPU7TU_js.SitemapSync; }
416
+ });
417
+ Object.defineProperty(exports, "generateSitemap", {
418
+ enumerable: true,
419
+ get: function () { return chunkSBVEYCSV_js.generateSitemap; }
420
+ });
421
+ Object.defineProperty(exports, "getRedirect", {
422
+ enumerable: true,
423
+ get: function () { return chunkSBVEYCSV_js.getRedirect; }
424
+ });
425
+ Object.defineProperty(exports, "getRobotsDirective", {
426
+ enumerable: true,
427
+ get: function () { return chunkSBVEYCSV_js.getRobotsDirective; }
428
+ });
429
+ Object.defineProperty(exports, "isIndexable", {
430
+ enumerable: true,
431
+ get: function () { return chunkSBVEYCSV_js.isIndexable; }
432
+ });
433
+ exports.ManagedContent = ManagedContent;
434
+ exports.ManagedFAQ = ManagedFAQ;
435
+ exports.ManagedInternalLinks = ManagedInternalLinks;
436
+ exports.ManagedNoScripts = ManagedNoScripts;
437
+ exports.ManagedSchema = ManagedSchema;
438
+ exports.ManagedScripts = ManagedScripts;
439
+ exports.createBreadcrumbSchema = createBreadcrumbSchema;
440
+ exports.createSchema = createSchema;
441
+ exports.default = ManagedSchema;
442
+ exports.getABVariant = getABVariant;
443
+ exports.getManagedContentData = getManagedContentData;
444
+ exports.getManagedMetadata = getManagedMetadata;
445
+ exports.getManagedMetadataWithAB = getManagedMetadataWithAB;
446
+ //# sourceMappingURL=index.js.map
447
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/seo/getManagedMetadata.ts","../../src/seo/ManagedSchema.tsx","../../src/seo/ManagedFAQ.tsx","../../src/seo/ManagedInternalLinks.tsx","../../src/seo/ManagedContent.tsx","../../src/seo/ManagedScripts.tsx"],"names":["getSEOPageData","getABTest","recordABImpression","getSchemaMarkups","jsx","jsxs","getFAQData","Fragment","getInternalLinks","getContentBlock","getManagedScripts"],"mappings":"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","file":"index.js","sourcesContent":["import type { Metadata } from 'next'\nimport { getSEOPageData, getABTest, recordABImpression } from './api'\nimport type { \n GetManagedMetadataOptions, \n ManagedMetadataResult,\n GetABVariantOptions,\n ABTestResult \n} from './types'\n\n/**\n * Get managed metadata for a page\n * \n * Use in generateMetadata() to fetch Portal-managed SEO data\n * \n * @example\n * ```tsx\n * export async function generateMetadata({ params }) {\n * return getManagedMetadata({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * path: `/services/${params.slug}`,\n * fallback: {\n * title: 'Our Services',\n * description: 'Learn about our services'\n * }\n * })\n * }\n * ```\n */\nexport async function getManagedMetadata(\n options: GetManagedMetadataOptions\n): Promise<ManagedMetadataResult> {\n const { projectId, path, fallback = {}, overrides = {} } = options\n\n const pageData = await getSEOPageData(projectId, path)\n\n // If no managed data, return fallback\n if (!pageData) {\n return {\n ...fallback,\n ...overrides,\n _managed: false,\n _source: 'fallback',\n } as ManagedMetadataResult\n }\n\n // Build metadata from managed values, falling back to provided fallbacks\n const metadata: ManagedMetadataResult = {\n _managed: true,\n _source: 'database',\n }\n\n // Title\n if (pageData.managed_title) {\n metadata.title = pageData.managed_title\n } else if (fallback.title) {\n metadata.title = fallback.title\n }\n\n // Description\n if (pageData.managed_description) {\n metadata.description = pageData.managed_description\n } else if (fallback.description) {\n metadata.description = fallback.description\n }\n\n // Keywords\n if (pageData.managed_keywords?.length) {\n metadata.keywords = pageData.managed_keywords\n } else if (fallback.keywords) {\n metadata.keywords = fallback.keywords\n }\n\n // Robots\n if (pageData.managed_robots) {\n metadata.robots = pageData.managed_robots\n }\n\n // Canonical\n if (pageData.managed_canonical) {\n metadata.alternates = {\n ...metadata.alternates,\n canonical: pageData.managed_canonical,\n }\n }\n\n // Open Graph\n const ogTitle = pageData.managed_og_title || pageData.managed_title\n const ogDescription = pageData.managed_og_description || pageData.managed_description\n const ogImage = pageData.managed_og_image\n\n if (ogTitle || ogDescription || ogImage) {\n metadata.openGraph = {\n ...(ogTitle && { title: ogTitle }),\n ...(ogDescription && { description: ogDescription }),\n ...(ogImage && { images: [{ url: ogImage }] }),\n }\n }\n\n // Twitter (use OG values as fallback)\n if (ogTitle || ogDescription || ogImage) {\n metadata.twitter = {\n card: 'summary_large_image',\n ...(ogTitle && { title: ogTitle }),\n ...(ogDescription && { description: ogDescription }),\n ...(ogImage && { images: [ogImage] }),\n }\n }\n\n // Apply overrides last\n return {\n ...metadata,\n ...overrides,\n _managed: true,\n _source: 'database',\n }\n}\n\n/**\n * Get A/B test variant for a field\n * \n * @example\n * ```tsx\n * const variant = await getABVariant({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * path: '/pricing',\n * field: 'title',\n * sessionId: cookies().get('session_id')?.value\n * })\n * \n * if (variant) {\n * // Use variant.value instead of default\n * }\n * ```\n */\nexport async function getABVariant(\n options: GetABVariantOptions\n): Promise<ABTestResult | null> {\n const { projectId, path, field, sessionId } = options\n\n const test = await getABTest(projectId, path, field)\n\n if (!test) {\n return null\n }\n\n // Determine variant based on session ID or random\n let variant: 'a' | 'b'\n \n if (sessionId) {\n // Consistent variant for same session\n const hash = sessionId.split('').reduce((acc, char) => {\n return ((acc << 5) - acc) + char.charCodeAt(0)\n }, 0)\n variant = (Math.abs(hash) % 100) < (test.traffic_split * 100) ? 'a' : 'b'\n } else {\n // Random variant\n variant = Math.random() < test.traffic_split ? 'a' : 'b'\n }\n\n // Record impression (fire and forget)\n recordABImpression(test.id, variant, sessionId).catch(() => {\n // Silently fail - don't block rendering\n })\n\n return {\n testId: test.id,\n variant,\n value: variant === 'a' ? test.variant_a : test.variant_b,\n }\n}\n\n/**\n * Get managed metadata with A/B test support\n * \n * Automatically applies running A/B test variants to metadata\n */\nexport async function getManagedMetadataWithAB(\n options: GetManagedMetadataOptions & { sessionId?: string }\n): Promise<ManagedMetadataResult> {\n const { sessionId, ...metadataOptions } = options\n \n // Get base metadata\n const metadata = await getManagedMetadata(metadataOptions)\n\n // Check for title A/B test\n const titleTest = await getABVariant({\n projectId: options.projectId,\n path: options.path,\n field: 'title',\n sessionId,\n })\n\n if (titleTest) {\n metadata.title = titleTest.value\n }\n\n // Check for description A/B test\n const descTest = await getABVariant({\n projectId: options.projectId,\n path: options.path,\n field: 'description',\n sessionId,\n })\n\n if (descTest) {\n metadata.description = descTest.value\n }\n\n return metadata\n}\n","import * as React from 'react'\nimport { getSchemaMarkups } from './api'\nimport type { ManagedSchemaProps } from './types'\n\n/**\n * ManagedSchema - Server Component that injects JSON-LD schema\n * \n * Fetches schema markup from Portal and renders as script tags\n * \n * @example\n * ```tsx\n * // app/services/[slug]/page.tsx\n * import { ManagedSchema } from '@uptrade/seo'\n * \n * export default async function ServicePage({ params }) {\n * return (\n * <>\n * <ManagedSchema \n * projectId={process.env.UPTRADE_PROJECT_ID!}\n * path={`/services/${params.slug}`}\n * />\n * <main>...</main>\n * </>\n * )\n * }\n * ```\n */\nexport async function ManagedSchema({\n projectId,\n path,\n additionalSchemas = [],\n includeTypes,\n excludeTypes,\n}: ManagedSchemaProps): Promise<React.ReactElement | null> {\n const schemas = await getSchemaMarkups(projectId, path, {\n includeTypes,\n excludeTypes,\n })\n\n // Combine managed schemas with additional ones\n const allSchemas = [\n ...schemas.map(s => s.schema_json),\n ...additionalSchemas,\n ]\n\n if (allSchemas.length === 0) {\n return null\n }\n\n // If multiple schemas, wrap in @graph\n const schemaContent = allSchemas.length === 1\n ? allSchemas[0]\n : {\n '@context': 'https://schema.org',\n '@graph': allSchemas.map(s => {\n // Remove @context from individual schemas when in graph\n const { '@context': _, ...rest } = s as Record<string, unknown>\n return rest\n }),\n }\n\n // Add @context if not in graph mode\n const finalSchema = allSchemas.length === 1\n ? { '@context': 'https://schema.org', ...schemaContent as Record<string, unknown> }\n : schemaContent\n\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{\n __html: JSON.stringify(finalSchema, null, 0),\n }}\n />\n )\n}\n\n/**\n * Generate schema for a specific type with managed data\n * \n * Helper to create common schema types\n */\nexport function createSchema(\n type: string,\n data: Record<string, unknown>\n): Record<string, unknown> {\n return {\n '@context': 'https://schema.org',\n '@type': type,\n ...data,\n }\n}\n\n/**\n * Create BreadcrumbList schema from path\n */\nexport function createBreadcrumbSchema(\n baseUrl: string,\n path: string,\n labels?: Record<string, string>\n): Record<string, unknown> {\n const segments = path.split('/').filter(Boolean)\n \n const items = segments.map((segment, index) => {\n const itemPath = '/' + segments.slice(0, index + 1).join('/')\n const label = labels?.[segment] || segment.replace(/-/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase())\n \n return {\n '@type': 'ListItem',\n position: index + 1,\n name: label,\n item: `${baseUrl}${itemPath}`,\n }\n })\n\n // Add home as first item\n items.unshift({\n '@type': 'ListItem',\n position: 0,\n name: 'Home',\n item: baseUrl,\n })\n\n // Re-number positions\n items.forEach((item, index) => {\n item.position = index + 1\n })\n\n return createSchema('BreadcrumbList', {\n itemListElement: items,\n })\n}\n\nexport default ManagedSchema\n","import * as React from 'react'\nimport { getFAQData } from './api'\nimport type { ManagedFAQProps, FAQItem } from './types'\nimport { createSchema } from './ManagedSchema'\n\n/**\n * Default FAQ item renderer\n */\nfunction DefaultFAQItem({ item, index }: { item: FAQItem; index: number }) {\n return (\n <div key={item.id} className=\"uptrade-faq-item\">\n <h3 className=\"uptrade-faq-question\">{item.question}</h3>\n <div \n className=\"uptrade-faq-answer\"\n dangerouslySetInnerHTML={{ __html: item.answer }}\n />\n </div>\n )\n}\n\n/**\n * Generate FAQ schema from items\n */\nfunction generateFAQSchema(items: FAQItem[]): Record<string, unknown> {\n return createSchema('FAQPage', {\n mainEntity: items\n .filter(item => item.is_visible)\n .map(item => ({\n '@type': 'Question',\n name: item.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: item.answer,\n },\n })),\n })\n}\n\n/**\n * ManagedFAQ - Server Component that renders FAQ section with schema\n * \n * Fetches FAQ content from Portal and renders with optional schema injection\n * \n * @example\n * ```tsx\n * // app/services/plumbing/page.tsx\n * import { ManagedFAQ } from '@uptrade/seo'\n * \n * export default async function PlumbingPage() {\n * return (\n * <main>\n * <h1>Plumbing Services</h1>\n * <section>\n * <ManagedFAQ \n * projectId={process.env.UPTRADE_PROJECT_ID!}\n * path=\"/services/plumbing\"\n * showTitle\n * includeSchema\n * />\n * </section>\n * </main>\n * )\n * }\n * ```\n */\nexport async function ManagedFAQ({\n projectId,\n path,\n className,\n renderItem,\n includeSchema = true,\n showTitle = true,\n}: ManagedFAQProps): Promise<React.ReactElement | null> {\n const faqData = await getFAQData(projectId, path)\n\n if (!faqData || !faqData.items?.length) {\n return null\n }\n\n const visibleItems = faqData.items.filter((item: FAQItem) => item.is_visible)\n \n if (visibleItems.length === 0) {\n return null\n }\n\n // Sort by order\n visibleItems.sort((a: FAQItem, b: FAQItem) => a.order - b.order)\n\n const shouldIncludeSchema = includeSchema && faqData.include_schema\n\n return (\n <>\n {shouldIncludeSchema && (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{\n __html: JSON.stringify(generateFAQSchema(visibleItems), null, 0),\n }}\n />\n )}\n <div className={className || 'uptrade-faq'}>\n {showTitle && faqData.title && (\n <h2 className=\"uptrade-faq-title\">{faqData.title}</h2>\n )}\n {faqData.description && (\n <p className=\"uptrade-faq-description\">{faqData.description}</p>\n )}\n <div className=\"uptrade-faq-items\">\n {visibleItems.map((item: FAQItem, index: number) => \n renderItem \n ? renderItem(item, index)\n : <DefaultFAQItem key={item.id} item={item} index={index} />\n )}\n </div>\n </div>\n </>\n )\n}\n\nexport default ManagedFAQ\n","import * as React from 'react'\nimport { getInternalLinks } from './api'\nimport type { ManagedInternalLinksProps, ManagedLink } from './types'\n\n/**\n * Default link renderer\n */\nfunction DefaultLinkRenderer({ link }: { link: ManagedLink }) {\n const href = link.target_url || link.target_path\n \n return (\n <a \n key={link.id}\n href={href}\n className=\"uptrade-internal-link\"\n >\n {link.anchor_text}\n </a>\n )\n}\n\n/**\n * ManagedInternalLinks - Server Component for AI-suggested internal links\n * \n * Fetches internal link suggestions from Portal and renders them\n * \n * @example\n * ```tsx\n * // In your article component\n * import { ManagedInternalLinks } from '@uptrade/seo'\n * \n * export default async function BlogPost({ params }) {\n * return (\n * <article>\n * <p>Your content here...</p>\n * \n * <ManagedInternalLinks \n * projectId={process.env.UPTRADE_PROJECT_ID!}\n * path={`/blog/${params.slug}`}\n * position=\"bottom\"\n * limit={5}\n * />\n * </article>\n * )\n * }\n * ```\n */\nexport async function ManagedInternalLinks({\n projectId,\n path,\n position = 'bottom',\n limit = 5,\n className,\n renderLink,\n}: ManagedInternalLinksProps): Promise<React.ReactElement | null> {\n const links = await getInternalLinks(projectId, path, { position, limit })\n\n if (!links.length) {\n return null\n }\n\n const containerClass = className || `uptrade-internal-links uptrade-internal-links--${position}`\n\n // Different layouts based on position\n if (position === 'inline') {\n // Inline links are meant to be inserted into content\n return (\n <span className={containerClass}>\n {links.map((link: ManagedLink) => \n renderLink ? renderLink(link) : <DefaultLinkRenderer key={link.id} link={link} />\n )}\n </span>\n )\n }\n\n if (position === 'sidebar') {\n return (\n <aside className={containerClass}>\n <h4 className=\"uptrade-internal-links-title\">Related Pages</h4>\n <ul className=\"uptrade-internal-links-list\">\n {links.map((link: ManagedLink) => (\n <li key={link.id}>\n {renderLink ? renderLink(link) : <DefaultLinkRenderer link={link} />}\n </li>\n ))}\n </ul>\n </aside>\n )\n }\n\n if (position === 'related') {\n return (\n <nav className={containerClass} aria-label=\"Related content\">\n <h3 className=\"uptrade-internal-links-title\">You May Also Like</h3>\n <div className=\"uptrade-internal-links-grid\">\n {links.map((link: ManagedLink) => (\n <div key={link.id} className=\"uptrade-internal-link-card\">\n {renderLink ? renderLink(link) : <DefaultLinkRenderer link={link} />}\n {link.context && (\n <p className=\"uptrade-internal-link-context\">{link.context}</p>\n )}\n </div>\n ))}\n </div>\n </nav>\n )\n }\n\n // Default: bottom position\n return (\n <div className={containerClass}>\n <h4 className=\"uptrade-internal-links-title\">Related Articles</h4>\n <ul className=\"uptrade-internal-links-list\">\n {links.map((link: ManagedLink) => (\n <li key={link.id}>\n {renderLink ? renderLink(link) : <DefaultLinkRenderer link={link} />}\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\nexport default ManagedInternalLinks\n","import * as React from 'react'\nimport { getContentBlock } from './api'\nimport type { ManagedContentProps, ManagedContentBlock } from './types'\n\n/**\n * Parse and render markdown content (basic support)\n * For full markdown, use a proper parser in your custom renderer\n */\nfunction renderMarkdown(content: string): string {\n return content\n // Headers\n .replace(/^### (.*$)/gim, '<h3>$1</h3>')\n .replace(/^## (.*$)/gim, '<h2>$1</h2>')\n .replace(/^# (.*$)/gim, '<h1>$1</h1>')\n // Bold\n .replace(/\\*\\*(.*)\\*\\*/gim, '<strong>$1</strong>')\n // Italic\n .replace(/\\*(.*)\\*/gim, '<em>$1</em>')\n // Links\n .replace(/\\[(.*?)\\]\\((.*?)\\)/gim, '<a href=\"$2\">$1</a>')\n // Paragraphs\n .replace(/\\n\\n/gim, '</p><p>')\n .replace(/^(.+)$/gim, '<p>$1</p>')\n}\n\n/**\n * ManagedContent - Server Component for CMS-controlled content blocks\n * \n * Fetches content sections from Portal and renders them\n * Supports HTML, Markdown, JSON, and React component references\n * \n * @example\n * ```tsx\n * // Hero section managed by Portal\n * import { ManagedContent } from '@uptrade/seo'\n * \n * export default async function ServicePage({ params }) {\n * return (\n * <main>\n * <ManagedContent \n * projectId={process.env.UPTRADE_PROJECT_ID!}\n * path={`/services/${params.slug}`}\n * section=\"hero\"\n * fallback={<DefaultHero />}\n * />\n * \n * <ManagedContent \n * projectId={process.env.UPTRADE_PROJECT_ID!}\n * path={`/services/${params.slug}`}\n * section=\"features\"\n * />\n * \n * <ManagedContent \n * projectId={process.env.UPTRADE_PROJECT_ID!}\n * path={`/services/${params.slug}`}\n * section=\"cta\"\n * />\n * </main>\n * )\n * }\n * ```\n */\nexport async function ManagedContent({\n projectId,\n path,\n section,\n fallback,\n className,\n components = {},\n}: ManagedContentProps): Promise<React.ReactElement | null> {\n const block = await getContentBlock(projectId, path, section)\n\n if (!block) {\n if (fallback) {\n return <>{fallback}</>\n }\n return null\n }\n\n const containerClass = className || `uptrade-content uptrade-content--${section}`\n\n // Handle different content types\n switch (block.content_type) {\n case 'html':\n return (\n <div \n className={containerClass}\n dangerouslySetInnerHTML={{ __html: block.content as string }}\n />\n )\n\n case 'markdown':\n const htmlContent = renderMarkdown(block.content as string)\n return (\n <div \n className={containerClass}\n dangerouslySetInnerHTML={{ __html: htmlContent }}\n />\n )\n\n case 'json':\n // JSON content for structured data - render as data attributes or custom handling\n const jsonData = typeof block.content === 'string' \n ? JSON.parse(block.content)\n : block.content\n\n return (\n <div \n className={containerClass}\n data-content={JSON.stringify(jsonData)}\n >\n {/* Render JSON structure - customize based on your needs */}\n {jsonData.title && <h2>{jsonData.title}</h2>}\n {jsonData.subtitle && <p className=\"subtitle\">{jsonData.subtitle}</p>}\n {jsonData.content && <div dangerouslySetInnerHTML={{ __html: jsonData.content }} />}\n {jsonData.items && (\n <ul>\n {jsonData.items.map((item: { text: string } | string, index: number) => (\n <li key={index}>{typeof item === 'string' ? item : item.text}</li>\n ))}\n </ul>\n )}\n </div>\n )\n\n case 'react':\n // React component reference - lookup from provided components map\n const componentData = typeof block.content === 'string'\n ? JSON.parse(block.content)\n : block.content as Record<string, unknown>\n\n const componentName = componentData.component as string\n const componentProps = componentData.props as Record<string, unknown> || {}\n\n const Component = components[componentName]\n \n if (!Component) {\n console.warn(`@uptrade/seo: Component \"${componentName}\" not found in components map`)\n return fallback ? <>{fallback}</> : null\n }\n\n return (\n <div className={containerClass}>\n <Component {...componentProps} />\n </div>\n )\n\n default:\n console.warn(`@uptrade/seo: Unknown content type \"${block.content_type}\"`)\n return fallback ? <>{fallback}</> : null\n }\n}\n\n/**\n * Get content block data without rendering\n * \n * Useful when you need to access the raw data\n */\nexport async function getManagedContentData(\n projectId: string,\n path: string,\n section: string\n): Promise<ManagedContentBlock | null> {\n return getContentBlock(projectId, path, section)\n}\n\nexport default ManagedContent\n","import * as React from 'react'\nimport { getManagedScripts } from './api'\nimport type { ManagedScriptsProps, ManagedScript } from './types'\n\n/**\n * ManagedScripts - Server Component for injecting tracking/analytics scripts\n * \n * Fetches scripts from Portal and renders them in the appropriate position\n * \n * @example\n * ```tsx\n * // app/layout.tsx\n * import { ManagedScripts } from '@uptrade/seo'\n * \n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <head>\n * <ManagedScripts \n * projectId={process.env.UPTRADE_PROJECT_ID!}\n * position=\"head\"\n * />\n * </head>\n * <body>\n * <ManagedScripts \n * projectId={process.env.UPTRADE_PROJECT_ID!}\n * position=\"body-start\"\n * />\n * {children}\n * <ManagedScripts \n * projectId={process.env.UPTRADE_PROJECT_ID!}\n * position=\"body-end\"\n * />\n * </body>\n * </html>\n * )\n * }\n * ```\n */\nexport async function ManagedScripts({\n projectId,\n position,\n path,\n}: ManagedScriptsProps): Promise<React.ReactElement | null> {\n const scripts = await getManagedScripts(projectId, position, path)\n\n if (!scripts.length) {\n return null\n }\n\n return (\n <>\n {scripts.map((script: ManagedScript) => {\n if (script.script_type === 'external') {\n // External script with src\n const attrs: Record<string, unknown> = {\n key: script.id,\n src: script.src,\n ...(script.async && { async: true }),\n ...(script.defer && { defer: true }),\n ...script.attributes,\n }\n\n return <script {...attrs} />\n }\n\n // Inline script\n return (\n <script\n key={script.id}\n dangerouslySetInnerHTML={{ __html: script.content || '' }}\n {...script.attributes}\n />\n )\n })}\n </>\n )\n}\n\n/**\n * NoScript fallback component\n * \n * Use for adding noscript content (like Google Tag Manager noscript)\n */\nexport async function ManagedNoScripts({\n projectId,\n path,\n}: {\n projectId: string\n path?: string\n}): Promise<React.ReactElement | null> {\n const scripts = await getManagedScripts(projectId, 'body-start', path)\n\n // Filter scripts that have noscript content\n const noscriptContent = scripts\n .filter((s: ManagedScript) => s.attributes?.noscript)\n .map((s: ManagedScript) => s.attributes?.noscript)\n .join('')\n\n if (!noscriptContent) {\n return null\n }\n\n return (\n <noscript dangerouslySetInnerHTML={{ __html: noscriptContent }} />\n )\n}\n\nexport default ManagedScripts\n"]}