@gradial/aci 0.1.45 → 0.1.47
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 +4 -4
- package/dist/astro/error-page.d.ts +56 -0
- package/dist/astro/error-page.js +79 -0
- package/dist/astro/index.d.ts +4 -0
- package/dist/astro/index.js +9 -0
- package/dist/audience-data-models.d.ts +142 -2
- package/dist/audience-data-models.js +2 -0
- package/dist/cli/compile-registry.d.mts +1 -5
- package/dist/cli/compile-registry.mjs +10 -25
- package/dist/cli/emit-error-pages.d.mts +39 -0
- package/dist/cli/emit-error-pages.mjs +402 -0
- package/dist/cli/validate-content.d.mts +1 -31
- package/dist/cli/validate-content.mjs +12 -50
- package/dist/cli/verify-next-cdn-routes.mjs +1 -0
- package/dist/content/default-error-page-html.d.ts +2 -0
- package/dist/content/default-error-page-html.js +6 -0
- package/dist/content/default-error-page.d.ts +23 -0
- package/dist/content/default-error-page.js +34 -0
- package/dist/content/error-page-kind.d.ts +57 -0
- package/dist/content/error-page-kind.js +106 -0
- package/dist/content/error-pages.d.ts +88 -0
- package/dist/content/error-pages.js +120 -0
- package/dist/content/index.d.ts +2 -0
- package/dist/content/index.js +2 -0
- package/dist/content/provider.d.ts +1 -1
- package/dist/content/resolve-slots.js +0 -1
- package/dist/content/types.d.ts +12 -2
- package/dist/internal/render-proof.d.ts +1 -0
- package/dist/internal/render-proof.js +197 -0
- package/dist/next/config.js +17 -0
- package/dist/next/error-page-instrumentation.d.ts +23 -0
- package/dist/next/error-page-instrumentation.js +36 -0
- package/dist/next/error-page-marker.d.ts +11 -0
- package/dist/next/error-page-marker.js +20 -0
- package/dist/next/error-pages.d.ts +52 -0
- package/dist/next/error-pages.js +94 -0
- package/dist/next/error-seat-payload.d.ts +33 -0
- package/dist/next/error-seat-payload.js +143 -0
- package/dist/next/error-seat.d.ts +57 -0
- package/dist/next/error-seat.js +83 -0
- package/dist/next/index.d.ts +4 -0
- package/dist/next/index.js +8 -0
- package/dist/next/middleware.js +9 -54
- package/dist/next/page.js +9 -4
- package/dist/next/personalization-host.d.ts +5 -0
- package/dist/next/server.js +88 -75
- package/dist/next/vercel-collect-sdk-route.js +6 -30
- package/dist/next/vercel-edge-projection-v1.d.ts +24 -0
- package/dist/next/vercel-edge-projection-v1.js +880 -0
- package/dist/next/vercel-s3-personalization.js +7 -11
- package/dist/providers/s3.d.ts +2 -4
- package/dist/providers/s3.js +173 -19
- package/dist/types/block-ref.d.ts +0 -2
- package/dist/types/block-ref.js +0 -1
- package/package.json +15 -9
- package/src/cli/compile-registry.mjs +10 -24
- package/src/cli/emit-error-pages.mjs +424 -0
- package/src/cli/validate-content.mjs +13 -52
- package/src/cli/verify-next-cdn-routes.mjs +6 -0
- package/src/types/block-ref.ts +0 -2
- package/templates/astro/starter-content/src/fixtures/atomicBlocks.ts +6 -7
- package/templates/astro/starter-content/src/fixtures/composition.ts +2 -3
- package/templates/astro/starter-content/src/fixtures/sections.ts +1 -2
- package/templates/astro/template/package.json.tmpl +1 -1
- package/templates/astro/template/src/aci/error-page-instrumentation.mjs +33 -0
- package/templates/astro/template/src/pages/404.astro +54 -0
- package/templates/astro/template/src/pages/500.astro +53 -0
- package/templates/astro/template/src/pages/[...slug].astro +15 -2
- package/templates/common/.agents/skills/authoring/SKILL.md +74 -11
- package/templates/common/.agents/skills/authoring/references/block-slots.md +0 -3
- package/templates/common/.content/config/robots.txt +4 -0
- package/templates/common/.content/config/site.json.tmpl +4 -0
- package/templates/common/.content/pages/404/_index.json +31 -0
- package/templates/common/.content/pages/error/_index.json +31 -0
- package/templates/common/.content/pages/home/_index.json +0 -10
- package/templates/common/.content/schemas/site.schema.json +9 -0
- package/templates/common/starter-content/.content/config/robots.txt +2 -0
- package/templates/common/starter-content/.content/config/site.json +4 -0
- package/templates/common/starter-content/.content/pages/404/_index.json +31 -0
- package/templates/common/starter-content/.content/pages/about/_index.json +0 -3
- package/templates/common/starter-content/.content/pages/error/_index.json +31 -0
- package/templates/common/starter-content/.content/pages/home/_index.json +21 -14
- package/templates/common/starter-content/.content/schemas/site.schema.json +9 -0
- package/templates/nextjs/template/package.json.tmpl +1 -1
- package/templates/nextjs/template/src/aci/error-page-instrumentation.d.mts +4 -0
- package/templates/nextjs/template/src/aci/error-page-instrumentation.mjs +38 -0
- package/templates/nextjs/template/src/app/error.tsx +18 -0
- package/templates/nextjs/template/src/app/not-found.tsx +13 -0
- package/src/types/block-ref.test.ts +0 -45
- package/templates/nextjs/template/src/app/collect/route.ts +0 -18
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Astro's native notFound error seat (authorable-error-pages REQ-7).
|
|
3
|
+
// Renders the page bound by site.json#errorPages.notFound through the normal
|
|
4
|
+
// SiteLayout path; static builds emit dist/404.html, which doubles as the
|
|
5
|
+
// direct /404/ route and the error surface (D-11 — the instrumentation on a
|
|
6
|
+
// direct visit is the accepted consequence). If the bound page cannot be
|
|
7
|
+
// loaded, the SDK degrades to its shipped default fragment — this seat never
|
|
8
|
+
// throws.
|
|
9
|
+
import { getErrorPageData, createRenderChildren } from '@gradial/aci/astro';
|
|
10
|
+
import { registry } from '../cms/registry';
|
|
11
|
+
import SiteLayout from '../layouts/SiteLayout.astro';
|
|
12
|
+
import { pushErrorPageView } from '../aci/error-page-instrumentation.mjs';
|
|
13
|
+
|
|
14
|
+
const errorPage = await getErrorPageData(Astro, 'notFound', { pushErrorPageView });
|
|
15
|
+
const data = errorPage.data;
|
|
16
|
+
const renderChildren = createRenderChildren(registry);
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
<SiteLayout
|
|
20
|
+
title={errorPage.meta.title}
|
|
21
|
+
description={errorPage.meta.description}
|
|
22
|
+
canonical={errorPage.meta.canonical}
|
|
23
|
+
siteName={errorPage.meta.siteName}
|
|
24
|
+
>
|
|
25
|
+
{data ? (
|
|
26
|
+
data.layout.slots.map((slot) => {
|
|
27
|
+
const blocks = data.slots[slot.name];
|
|
28
|
+
if (!blocks?.length) return null;
|
|
29
|
+
const rendered = renderChildren(blocks);
|
|
30
|
+
if (slot.name === 'main') {
|
|
31
|
+
return (
|
|
32
|
+
<main id="content-main">
|
|
33
|
+
{rendered.map((child) => {
|
|
34
|
+
const Comp = child.Component as any;
|
|
35
|
+
return Comp ? <Comp {...child.props} /> : null;
|
|
36
|
+
})}
|
|
37
|
+
</main>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
return rendered.map((child) => {
|
|
41
|
+
const Comp = child.Component as any;
|
|
42
|
+
return Comp ? <Comp {...child.props} /> : null;
|
|
43
|
+
});
|
|
44
|
+
})
|
|
45
|
+
) : (
|
|
46
|
+
<Fragment set:html={errorPage.fallbackHtml} />
|
|
47
|
+
)}
|
|
48
|
+
<!-- D-14 error-surface analytics: ONE page_view push with the visitor's
|
|
49
|
+
requested path. The push body is site-owned (D-15): the SDK serializes
|
|
50
|
+
src/aci/error-page-instrumentation.mjs into this tag, injected like
|
|
51
|
+
SiteLayout's collectTag; inline scripts execute here — Astro serves
|
|
52
|
+
real HTML documents (unlike the Next flight-rendered seat). -->
|
|
53
|
+
<Fragment set:html={errorPage.instrumentationTag} />
|
|
54
|
+
</SiteLayout>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Astro's native catchAll (500) error seat (authorable-error-pages REQ-7).
|
|
3
|
+
// Renders the page bound by site.json#errorPages.catchAll through the normal
|
|
4
|
+
// SiteLayout path. Static builds emit dist/500.html for the hosting layer;
|
|
5
|
+
// server output serves this seat when a route throws during on-demand
|
|
6
|
+
// rendering. If the bound page cannot be loaded, the SDK degrades to its
|
|
7
|
+
// shipped default fragment — this seat never throws.
|
|
8
|
+
import { getErrorPageData, createRenderChildren } from '@gradial/aci/astro';
|
|
9
|
+
import { registry } from '../cms/registry';
|
|
10
|
+
import SiteLayout from '../layouts/SiteLayout.astro';
|
|
11
|
+
import { pushErrorPageView } from '../aci/error-page-instrumentation.mjs';
|
|
12
|
+
|
|
13
|
+
const errorPage = await getErrorPageData(Astro, 'catchAll', { pushErrorPageView });
|
|
14
|
+
const data = errorPage.data;
|
|
15
|
+
const renderChildren = createRenderChildren(registry);
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
<SiteLayout
|
|
19
|
+
title={errorPage.meta.title}
|
|
20
|
+
description={errorPage.meta.description}
|
|
21
|
+
canonical={errorPage.meta.canonical}
|
|
22
|
+
siteName={errorPage.meta.siteName}
|
|
23
|
+
>
|
|
24
|
+
{data ? (
|
|
25
|
+
data.layout.slots.map((slot) => {
|
|
26
|
+
const blocks = data.slots[slot.name];
|
|
27
|
+
if (!blocks?.length) return null;
|
|
28
|
+
const rendered = renderChildren(blocks);
|
|
29
|
+
if (slot.name === 'main') {
|
|
30
|
+
return (
|
|
31
|
+
<main id="content-main">
|
|
32
|
+
{rendered.map((child) => {
|
|
33
|
+
const Comp = child.Component as any;
|
|
34
|
+
return Comp ? <Comp {...child.props} /> : null;
|
|
35
|
+
})}
|
|
36
|
+
</main>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return rendered.map((child) => {
|
|
40
|
+
const Comp = child.Component as any;
|
|
41
|
+
return Comp ? <Comp {...child.props} /> : null;
|
|
42
|
+
});
|
|
43
|
+
})
|
|
44
|
+
) : (
|
|
45
|
+
<Fragment set:html={errorPage.fallbackHtml} />
|
|
46
|
+
)}
|
|
47
|
+
<!-- D-14 error-surface analytics: ONE page_view push with the visitor's
|
|
48
|
+
requested path. The push body is site-owned (D-15): the SDK serializes
|
|
49
|
+
src/aci/error-page-instrumentation.mjs into this tag, injected like
|
|
50
|
+
SiteLayout's collectTag; inline scripts execute here — Astro serves
|
|
51
|
+
real HTML documents (unlike the Next flight-rendered seat). -->
|
|
52
|
+
<Fragment set:html={errorPage.instrumentationTag} />
|
|
53
|
+
</SiteLayout>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import { getGradialStaticPaths, getPageData, createRenderChildren } from '@gradial/aci/astro';
|
|
2
|
+
import { getGradialStaticPaths, getPageData, createRenderChildren, PageNotFoundError, type PageData } from '@gradial/aci/astro';
|
|
3
3
|
import { registry } from '../cms/registry';
|
|
4
4
|
import SiteLayout from '../layouts/SiteLayout.astro';
|
|
5
5
|
|
|
@@ -7,7 +7,20 @@ export const getStaticPaths = getGradialStaticPaths;
|
|
|
7
7
|
|
|
8
8
|
// SDK owns route normalization, content loading, metadata, layout/slot
|
|
9
9
|
// resolution, and collect-tag emission. No FileContentProvider imports.
|
|
10
|
-
|
|
10
|
+
//
|
|
11
|
+
// Server output: unknown routes raise PageNotFoundError here; rewrite to the
|
|
12
|
+
// 404 seat so misses answer HTTP 404, not 500 (authorable-error-pages D-10).
|
|
13
|
+
// src/pages/404.astro is load-bearing for this rewrite — deleting it turns
|
|
14
|
+
// every miss into a 500.
|
|
15
|
+
// Static output never takes this branch — getStaticPaths only emits known
|
|
16
|
+
// routes.
|
|
17
|
+
let data: PageData;
|
|
18
|
+
try {
|
|
19
|
+
data = await getPageData(Astro);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
if (error instanceof PageNotFoundError) return Astro.rewrite('/404/');
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
11
24
|
const renderChildren = createRenderChildren(registry);
|
|
12
25
|
---
|
|
13
26
|
|
|
@@ -98,7 +98,6 @@ The `home` slug is special-cased to route `/`. All other slugs map directly.
|
|
|
98
98
|
|
|
99
99
|
```json
|
|
100
100
|
{
|
|
101
|
-
"$type": "component",
|
|
102
101
|
"id": "hero-section",
|
|
103
102
|
"component": "home_hero",
|
|
104
103
|
"props": {
|
|
@@ -110,7 +109,6 @@ The `home` slug is special-cased to route `/`. All other slugs map directly.
|
|
|
110
109
|
```
|
|
111
110
|
|
|
112
111
|
- `component` must match a contract `id` exactly.
|
|
113
|
-
- Every embedded block must declare `"$type": "component"`.
|
|
114
112
|
- `props` must validate against the contract's Zod schema.
|
|
115
113
|
- `id` is unique within the page.
|
|
116
114
|
|
|
@@ -143,14 +141,12 @@ export const containerContract = defineComponentContract({
|
|
|
143
141
|
**Content JSON:**
|
|
144
142
|
```json
|
|
145
143
|
{
|
|
146
|
-
"$type": "component",
|
|
147
144
|
"id": "cta-section",
|
|
148
145
|
"component": "container",
|
|
149
146
|
"props": {
|
|
150
147
|
"className": "space-y-4",
|
|
151
148
|
"content": [
|
|
152
149
|
{
|
|
153
|
-
"$type": "component",
|
|
154
150
|
"id": "primary-cta",
|
|
155
151
|
"component": "button",
|
|
156
152
|
"props": {
|
|
@@ -160,7 +156,6 @@ export const containerContract = defineComponentContract({
|
|
|
160
156
|
}
|
|
161
157
|
},
|
|
162
158
|
{
|
|
163
|
-
"$type": "component",
|
|
164
159
|
"id": "secondary-cta",
|
|
165
160
|
"component": "button",
|
|
166
161
|
"props": {
|
|
@@ -187,7 +182,6 @@ The `button` component is a common atomic block:
|
|
|
187
182
|
|
|
188
183
|
```json
|
|
189
184
|
{
|
|
190
|
-
"$type": "component",
|
|
191
185
|
"id": "cta-button",
|
|
192
186
|
"component": "button",
|
|
193
187
|
"props": {
|
|
@@ -244,6 +238,77 @@ Global elements (navigation, footer, branding, SEO) live in
|
|
|
244
238
|
}
|
|
245
239
|
```
|
|
246
240
|
|
|
241
|
+
### Error Pages
|
|
242
|
+
|
|
243
|
+
Sites bind their error pages in `site.json` via `errorPages`:
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"errorPages": {
|
|
248
|
+
"notFound": "/404/",
|
|
249
|
+
"catchAll": "/error/"
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
- Each binding is a route path resolving to an **ordinary content page**
|
|
255
|
+
(`.content/pages/404/_index.json`, `.content/pages/error/_index.json`) —
|
|
256
|
+
authored with normal layouts and components like any other page.
|
|
257
|
+
`notFound` serves unknown routes with HTTP 404; `catchAll` serves
|
|
258
|
+
application errors (500-class).
|
|
259
|
+
- Error pages stay out of discovery: set `metadata.sitemap.visible: false`
|
|
260
|
+
on both pages, and the template `robots.txt` disallows both routes.
|
|
261
|
+
- If `errorPages` is absent, the build warns loudly and ships a
|
|
262
|
+
branded-neutral default page (warn-then-enforce migration: absent
|
|
263
|
+
bindings will eventually fail the build, so author them). Present but
|
|
264
|
+
broken bindings — malformed paths, no matching page, unpublished page —
|
|
265
|
+
fail the build immediately.
|
|
266
|
+
- Error pages are base-audience only: no personalization, audience, or
|
|
267
|
+
experiment overlays (validation rejects them), and collect/assignment
|
|
268
|
+
markup is stripped from materialized copies.
|
|
269
|
+
- Analytics: error-surface renders push one `page_view` event to
|
|
270
|
+
`window.dataLayer` with `page_type` (`not_found` | `error`),
|
|
271
|
+
`page_path` (the visitor's requested path), `page_location`,
|
|
272
|
+
`page_referrer`, and `page_title`. The push body is site-owned
|
|
273
|
+
(`src/aci/error-page-instrumentation.mjs` — see the GTM/GA4 section
|
|
274
|
+
below); the SDK wrappers handle delivery.
|
|
275
|
+
|
|
276
|
+
### Error-page analytics (GTM/GA4)
|
|
277
|
+
|
|
278
|
+
The push body is YOURS: it lives in the site-owned
|
|
279
|
+
`src/aci/error-page-instrumentation.mjs`, whose `pushErrorPageView`
|
|
280
|
+
function every error surface (Next seats, Astro seats, the emitted static
|
|
281
|
+
`500.html`) executes. The scaffolded default pushes one event to
|
|
282
|
+
`window.dataLayer`:
|
|
283
|
+
|
|
284
|
+
```js
|
|
285
|
+
{ event: 'page_view', page_type: 'not_found' | 'error',
|
|
286
|
+
page_path, page_location, page_referrer, page_title }
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
- **Customize** — edit the function in place. It must stay self-contained
|
|
290
|
+
(browser globals only, no imports, no closed-over identifiers): some
|
|
291
|
+
surfaces execute it stringified.
|
|
292
|
+
- **Disable** — make the function body a no-op. That turns off error-page
|
|
293
|
+
analytics on every surface, and no GTM-side suppression is needed.
|
|
294
|
+
|
|
295
|
+
Container-side dedup is only needed when you KEEP the default push
|
|
296
|
+
alongside automatic GA4 page views: because the event name is `page_view`,
|
|
297
|
+
either disable `send_page_view` and drive all page views from the
|
|
298
|
+
dataLayer, or add a trigger exception on the config tag for error
|
|
299
|
+
surfaces. The stable suppression signal is the `data-aci-error-page`
|
|
300
|
+
attribute (values `not_found` | `error`; the attribute is SDK-owned and
|
|
301
|
+
stable regardless of what your push does): present on the instrumentation
|
|
302
|
+
script tag (Astro, parse-time) and on a server-rendered marker element
|
|
303
|
+
(Next, in the DOM before container load), so container-load triggers can
|
|
304
|
+
gate on it in both frameworks. If you leave automatic page views on and
|
|
305
|
+
also keep the default push, error pages will double-count — that is a
|
|
306
|
+
container configuration choice, not an SDK default.
|
|
307
|
+
|
|
308
|
+
Direct visits to `/404/` and `/error/` do not carry error context and do
|
|
309
|
+
not push the event (Astro static output is the one exception: its
|
|
310
|
+
`404.html` doubles as the direct route).
|
|
311
|
+
|
|
247
312
|
### ID Conventions
|
|
248
313
|
|
|
249
314
|
- Every block must have a unique `id` within the page.
|
|
@@ -417,7 +482,6 @@ framework.
|
|
|
417
482
|
```json
|
|
418
483
|
// .content/pages/home/_index.json (inside regions.main)
|
|
419
484
|
{
|
|
420
|
-
"$type": "component",
|
|
421
485
|
"id": "features",
|
|
422
486
|
"component": "feature_showcase",
|
|
423
487
|
"props": {
|
|
@@ -506,10 +570,9 @@ export default [
|
|
|
506
570
|
];
|
|
507
571
|
```
|
|
508
572
|
|
|
509
|
-
Fragment content lives in `.content/fragments/{id}/_index.json` and
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
alongside page components.
|
|
573
|
+
Fragment content lives in `.content/fragments/{id}/_index.json` and has
|
|
574
|
+
a `component` + `props` just like page blocks. Chrome components (Header,
|
|
575
|
+
Footer) are registered in the registry alongside page components.
|
|
513
576
|
|
|
514
577
|
The `layout` field in page JSON is **required** — there is no implicit
|
|
515
578
|
default. Every page must declare which layout it uses.
|
|
@@ -113,14 +113,12 @@ type RenderChildren<T extends readonly BlockRef[]> = (blocks: T) => Promise<Reac
|
|
|
113
113
|
|
|
114
114
|
```json
|
|
115
115
|
{
|
|
116
|
-
"$type": "component",
|
|
117
116
|
"id": "cta-section",
|
|
118
117
|
"component": "container",
|
|
119
118
|
"props": {
|
|
120
119
|
"theme": "dark",
|
|
121
120
|
"blocks": [
|
|
122
121
|
{
|
|
123
|
-
"$type": "component",
|
|
124
122
|
"id": "primary-cta",
|
|
125
123
|
"component": "callout",
|
|
126
124
|
"props": {
|
|
@@ -129,7 +127,6 @@ type RenderChildren<T extends readonly BlockRef[]> = (blocks: T) => Promise<Reac
|
|
|
129
127
|
}
|
|
130
128
|
},
|
|
131
129
|
{
|
|
132
|
-
"$type": "component",
|
|
133
130
|
"id": "heading",
|
|
134
131
|
"component": "heading",
|
|
135
132
|
"props": {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$type": "page",
|
|
3
|
+
"id": "meridian-not-found",
|
|
4
|
+
"status": "published",
|
|
5
|
+
"layout": "default",
|
|
6
|
+
"metadata": {
|
|
7
|
+
"title": "Page not found — Meridian",
|
|
8
|
+
"description": "The page you are looking for does not exist.",
|
|
9
|
+
"sitemap": { "visible": false }
|
|
10
|
+
},
|
|
11
|
+
"regions": {
|
|
12
|
+
"main": [
|
|
13
|
+
{
|
|
14
|
+
"id": "not-found-hero",
|
|
15
|
+
"component": "home_hero",
|
|
16
|
+
"props": {
|
|
17
|
+
"eyebrow": "404",
|
|
18
|
+
"headline": "This page drifted out of orbit.",
|
|
19
|
+
"description": "The page you are looking for does not exist or has moved. Check the address, or head back to the homepage.",
|
|
20
|
+
"ctaLabel": "Back to home",
|
|
21
|
+
"ctaHref": "/",
|
|
22
|
+
"image": {
|
|
23
|
+
"$type": "dam.assetRef",
|
|
24
|
+
"assetId": "ast_site_home_hero",
|
|
25
|
+
"alt": "Light abstract background with satellite constellation"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$type": "page",
|
|
3
|
+
"id": "meridian-error",
|
|
4
|
+
"status": "published",
|
|
5
|
+
"layout": "default",
|
|
6
|
+
"metadata": {
|
|
7
|
+
"title": "Something went wrong — Meridian",
|
|
8
|
+
"description": "An unexpected error occurred while serving this page.",
|
|
9
|
+
"sitemap": { "visible": false }
|
|
10
|
+
},
|
|
11
|
+
"regions": {
|
|
12
|
+
"main": [
|
|
13
|
+
{
|
|
14
|
+
"id": "error-hero",
|
|
15
|
+
"component": "home_hero",
|
|
16
|
+
"props": {
|
|
17
|
+
"eyebrow": "Temporary interruption",
|
|
18
|
+
"headline": "Something went wrong on our end.",
|
|
19
|
+
"description": "An unexpected error occurred while serving this page. Please try again in a moment, or head back to the homepage.",
|
|
20
|
+
"ctaLabel": "Back to home",
|
|
21
|
+
"ctaHref": "/",
|
|
22
|
+
"image": {
|
|
23
|
+
"$type": "dam.assetRef",
|
|
24
|
+
"assetId": "ast_site_home_hero",
|
|
25
|
+
"alt": "Light abstract background with satellite constellation"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"regions": {
|
|
12
12
|
"main": [
|
|
13
13
|
{
|
|
14
|
-
"$type": "component",
|
|
15
14
|
"id": "hero",
|
|
16
15
|
"component": "home_hero",
|
|
17
16
|
"props": {
|
|
@@ -28,7 +27,6 @@
|
|
|
28
27
|
}
|
|
29
28
|
},
|
|
30
29
|
{
|
|
31
|
-
"$type": "component",
|
|
32
30
|
"id": "why-meridian",
|
|
33
31
|
"component": "feature_grid",
|
|
34
32
|
"props": {
|
|
@@ -36,7 +34,6 @@
|
|
|
36
34
|
"subtitle": "Engineered for the edges of the world.",
|
|
37
35
|
"features": [
|
|
38
36
|
{
|
|
39
|
-
"$type": "component",
|
|
40
37
|
"id": "global-coverage",
|
|
41
38
|
"component": "feature_card",
|
|
42
39
|
"props": {
|
|
@@ -46,7 +43,6 @@
|
|
|
46
43
|
}
|
|
47
44
|
},
|
|
48
45
|
{
|
|
49
|
-
"$type": "component",
|
|
50
46
|
"id": "low-latency",
|
|
51
47
|
"component": "feature_card",
|
|
52
48
|
"props": {
|
|
@@ -56,7 +52,6 @@
|
|
|
56
52
|
}
|
|
57
53
|
},
|
|
58
54
|
{
|
|
59
|
-
"$type": "component",
|
|
60
55
|
"id": "easy-setup",
|
|
61
56
|
"component": "feature_card",
|
|
62
57
|
"props": {
|
|
@@ -69,7 +64,6 @@
|
|
|
69
64
|
}
|
|
70
65
|
},
|
|
71
66
|
{
|
|
72
|
-
"$type": "component",
|
|
73
67
|
"id": "personalization-choice",
|
|
74
68
|
"component": "personalization_choice",
|
|
75
69
|
"props": {
|
|
@@ -81,7 +75,6 @@
|
|
|
81
75
|
}
|
|
82
76
|
},
|
|
83
77
|
{
|
|
84
|
-
"$type": "component",
|
|
85
78
|
"id": "stats",
|
|
86
79
|
"component": "stats_bar",
|
|
87
80
|
"props": {
|
|
@@ -94,7 +87,6 @@
|
|
|
94
87
|
}
|
|
95
88
|
},
|
|
96
89
|
{
|
|
97
|
-
"$type": "component",
|
|
98
90
|
"id": "cta",
|
|
99
91
|
"component": "container",
|
|
100
92
|
"props": {
|
|
@@ -102,7 +94,6 @@
|
|
|
102
94
|
"className": "items-center justify-center text-center",
|
|
103
95
|
"content": [
|
|
104
96
|
{
|
|
105
|
-
"$type": "component",
|
|
106
97
|
"id": "cta-primary",
|
|
107
98
|
"component": "button",
|
|
108
99
|
"props": {
|
|
@@ -114,7 +105,6 @@
|
|
|
114
105
|
}
|
|
115
106
|
},
|
|
116
107
|
{
|
|
117
|
-
"$type": "component",
|
|
118
108
|
"id": "cta-secondary",
|
|
119
109
|
"component": "button",
|
|
120
110
|
"props": {
|
|
@@ -7,6 +7,15 @@
|
|
|
7
7
|
"additionalProperties": true,
|
|
8
8
|
"properties": {
|
|
9
9
|
"$type": { "const": "site" },
|
|
10
|
+
"errorPages": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"required": ["notFound", "catchAll"],
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"properties": {
|
|
15
|
+
"notFound": { "type": "string", "pattern": "^/(?:[A-Za-z0-9._~-]+/)+$" },
|
|
16
|
+
"catchAll": { "type": "string", "pattern": "^/(?:[A-Za-z0-9._~-]+/)+$" }
|
|
17
|
+
}
|
|
18
|
+
},
|
|
10
19
|
"id": { "type": "string", "minLength": 1 },
|
|
11
20
|
"status": { "type": "string", "minLength": 1 },
|
|
12
21
|
"title": { "type": "string", "minLength": 1 },
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$type": "page",
|
|
3
|
+
"id": "meridian-not-found",
|
|
4
|
+
"status": "published",
|
|
5
|
+
"layout": "default",
|
|
6
|
+
"metadata": {
|
|
7
|
+
"title": "Page not found — Meridian",
|
|
8
|
+
"description": "The page you are looking for does not exist.",
|
|
9
|
+
"sitemap": { "visible": false }
|
|
10
|
+
},
|
|
11
|
+
"regions": {
|
|
12
|
+
"main": [
|
|
13
|
+
{
|
|
14
|
+
"id": "not-found-hero",
|
|
15
|
+
"component": "home_hero",
|
|
16
|
+
"props": {
|
|
17
|
+
"eyebrow": "404",
|
|
18
|
+
"headline": "This page drifted out of orbit.",
|
|
19
|
+
"description": "The page you are looking for does not exist or has moved. Check the address, or head back to the homepage.",
|
|
20
|
+
"ctaLabel": "Back to home",
|
|
21
|
+
"ctaHref": "/",
|
|
22
|
+
"image": {
|
|
23
|
+
"$type": "dam.assetRef",
|
|
24
|
+
"assetId": "ast_site_home_hero",
|
|
25
|
+
"alt": "Light abstract background with satellite constellation"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"regions": {
|
|
12
12
|
"main": [
|
|
13
13
|
{
|
|
14
|
-
"$type": "component",
|
|
15
14
|
"id": "about-hero",
|
|
16
15
|
"component": "home_hero",
|
|
17
16
|
"props": {
|
|
@@ -28,14 +27,12 @@
|
|
|
28
27
|
}
|
|
29
28
|
},
|
|
30
29
|
{
|
|
31
|
-
"$type": "component",
|
|
32
30
|
"id": "about-actions",
|
|
33
31
|
"component": "container",
|
|
34
32
|
"props": {
|
|
35
33
|
"className": "items-center justify-center text-center",
|
|
36
34
|
"content": [
|
|
37
35
|
{
|
|
38
|
-
"$type": "component",
|
|
39
36
|
"id": "home-link",
|
|
40
37
|
"component": "button",
|
|
41
38
|
"props": {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$type": "page",
|
|
3
|
+
"id": "meridian-error",
|
|
4
|
+
"status": "published",
|
|
5
|
+
"layout": "default",
|
|
6
|
+
"metadata": {
|
|
7
|
+
"title": "Something went wrong — Meridian",
|
|
8
|
+
"description": "An unexpected error occurred while serving this page.",
|
|
9
|
+
"sitemap": { "visible": false }
|
|
10
|
+
},
|
|
11
|
+
"regions": {
|
|
12
|
+
"main": [
|
|
13
|
+
{
|
|
14
|
+
"id": "error-hero",
|
|
15
|
+
"component": "home_hero",
|
|
16
|
+
"props": {
|
|
17
|
+
"eyebrow": "Temporary interruption",
|
|
18
|
+
"headline": "Something went wrong on our end.",
|
|
19
|
+
"description": "An unexpected error occurred while serving this page. Please try again in a moment, or head back to the homepage.",
|
|
20
|
+
"ctaLabel": "Back to home",
|
|
21
|
+
"ctaHref": "/",
|
|
22
|
+
"image": {
|
|
23
|
+
"$type": "dam.assetRef",
|
|
24
|
+
"assetId": "ast_site_home_hero",
|
|
25
|
+
"alt": "Light abstract background with satellite constellation"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
}
|