weg-shared-layout 0.0.2 → 0.0.4
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/dist/types/components/weg-footer/weg-footer.d.ts +32 -47
- package/dist/types/components.d.ts +5 -79
- package/dist/weg-shared-layout/index-C8BdwtPR.js +4625 -0
- package/dist/weg-shared-layout/index-C8BdwtPR.js.map +1 -0
- package/dist/weg-shared-layout/index.esm.js +14 -1
- package/dist/weg-shared-layout/index.esm.js.map +1 -0
- package/dist/weg-shared-layout/my-component.entry.js +34 -0
- package/dist/weg-shared-layout/my-component.entry.js.map +1 -0
- package/dist/{cjs/index.cjs.js → weg-shared-layout/utils-DhW431pq.js} +4 -3
- package/dist/weg-shared-layout/utils-DhW431pq.js.map +1 -0
- package/dist/{esm/my-component_2.entry.js → weg-shared-layout/weg-footer.entry.js} +62 -138
- package/dist/weg-shared-layout/weg-footer.entry.js.map +1 -0
- package/dist/weg-shared-layout/weg-shared-layout.esm.js +50 -1
- package/dist/weg-shared-layout/weg-shared-layout.esm.js.map +1 -0
- package/package.json +7 -3
- package/readme.md +220 -154
- package/dist/cjs/app-globals-V2Kpy_OQ.js +0 -5
- package/dist/cjs/index-CmiaQ_Dj.js +0 -1612
- package/dist/cjs/loader.cjs.js +0 -13
- package/dist/cjs/my-component_2.cjs.entry.js +0 -249
- package/dist/cjs/weg-shared-layout.cjs.js +0 -25
- package/dist/collection/collection-manifest.json +0 -14
- package/dist/collection/components/my-component/my-component.cmp.test.js +0 -27
- package/dist/collection/components/my-component/my-component.css +0 -3
- package/dist/collection/components/my-component/my-component.js +0 -95
- package/dist/collection/components/weg-footer/icons/instagram.svg +0 -5
- package/dist/collection/components/weg-footer/icons/linkedin.svg +0 -3
- package/dist/collection/components/weg-footer/icons/tiktok.svg +0 -3
- package/dist/collection/components/weg-footer/icons/youtube.svg +0 -4
- package/dist/collection/components/weg-footer/weg-footer.css +0 -236
- package/dist/collection/components/weg-footer/weg-footer.js +0 -412
- package/dist/collection/index.js +0 -10
- package/dist/collection/utils/utils.js +0 -3
- package/dist/collection/utils/utils.unit.test.js +0 -16
- package/dist/components/index.js +0 -1
- package/dist/components/my-component.js +0 -1
- package/dist/components/p-BTQYW5OR.js +0 -1
- package/dist/components/weg-footer.js +0 -1
- package/dist/esm/app-globals-DQuL1Twl.js +0 -3
- package/dist/esm/index-QiJxC4Ow.js +0 -1606
- package/dist/esm/index.js +0 -5
- package/dist/esm/loader.js +0 -11
- package/dist/esm/weg-shared-layout.js +0 -21
- package/dist/index.cjs.js +0 -1
- package/dist/index.js +0 -1
- package/dist/weg-shared-layout/p-67d9c345.entry.js +0 -1
- package/dist/weg-shared-layout/p-DQuL1Twl.js +0 -1
- package/dist/weg-shared-layout/p-QiJxC4Ow.js +0 -2
package/readme.md
CHANGED
|
@@ -1,114 +1,214 @@
|
|
|
1
1
|
[](https://stenciljs.com)
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# weg-shared-layout
|
|
4
4
|
|
|
5
|
-
>
|
|
5
|
+
> Shared layout Web Components (Stencil).
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Install:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```bash
|
|
10
|
+
npm i weg-shared-layout
|
|
11
|
+
```
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
## How it works
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
`<weg-footer>` is a **dumb / presentational** Web Component. It does **not** fetch data itself. Your host app calls the layout API, then passes the resulting object into the component via the `data` prop.
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
This keeps the component framework-agnostic, lets you share the same response with `<weg-header>` (coming soon), and means HTTP concerns like auth, caching, retries, SSR, and error handling live in your app — where they belong.
|
|
18
|
+
|
|
19
|
+
## Layout API
|
|
20
|
+
|
|
21
|
+
Call this endpoint from your host app to retrieve the data:
|
|
16
22
|
|
|
17
|
-
```bash
|
|
18
|
-
git clone https://github.com/stenciljs/component-starter.git my-component
|
|
19
|
-
cd my-component
|
|
20
|
-
git remote rm origin
|
|
21
23
|
```
|
|
24
|
+
GET https://weg-payload-test.vercel.app/api/layout
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Response shape:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"header": {},
|
|
32
|
+
"footer": {
|
|
33
|
+
"social": [
|
|
34
|
+
{ "platform": "LinkedIn", "href": "https://www.linkedin.com/" },
|
|
35
|
+
{ "platform": "Instagram", "href": "https://www.instagram.com/" },
|
|
36
|
+
{ "platform": "TikTok", "href": "https://www.tiktok.com/" },
|
|
37
|
+
{ "platform": "YouTube", "href": "https://www.youtube.com/" }
|
|
38
|
+
],
|
|
39
|
+
"standardLinks": [
|
|
40
|
+
{ "label": "About Us", "href": "/about" },
|
|
41
|
+
{ "label": "Privacy Policy", "href": "/privacy" },
|
|
42
|
+
{ "label": "Terms of Use", "href": "/terms" },
|
|
43
|
+
{ "label": "Cookie Policy", "href": "/cookies" },
|
|
44
|
+
{ "label": "Accessibility Statement", "href": "/accessibility" }
|
|
45
|
+
],
|
|
46
|
+
"credits": "Warwick Employment Group is a department of the Campus and Commercial Services Group at the University of Warwick.",
|
|
47
|
+
"copyright": "Copyright © Warwick Employment Group."
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Only `social.platform` values of `LinkedIn`, `Instagram`, `TikTok`, and `YouTube` render an icon. Items with missing/invalid fields are silently dropped.
|
|
22
53
|
|
|
23
|
-
|
|
54
|
+
## Using in Angular
|
|
55
|
+
|
|
56
|
+
This guide assumes a modern Angular project (v17+, **standalone components**) — the default for `ng new`. There's an `NgModule` section further down for older apps.
|
|
57
|
+
|
|
58
|
+
### 1. Install the package
|
|
24
59
|
|
|
25
60
|
```bash
|
|
26
|
-
npm
|
|
27
|
-
|
|
61
|
+
npm i weg-shared-layout
|
|
62
|
+
# or: pnpm add weg-shared-layout
|
|
63
|
+
# or: yarn add weg-shared-layout
|
|
28
64
|
```
|
|
29
65
|
|
|
30
|
-
|
|
66
|
+
### 2. Register the custom elements (once, at startup)
|
|
31
67
|
|
|
32
|
-
|
|
33
|
-
|
|
68
|
+
Stencil ships a loader that calls `customElements.define()` for every component in the package. Call it **once** before Angular bootstraps your app, otherwise the browser sees `<weg-footer>` as an unknown element and renders nothing.
|
|
69
|
+
|
|
70
|
+
Edit `src/main.ts`:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { bootstrapApplication } from '@angular/platform-browser';
|
|
74
|
+
import { defineCustomElements } from 'weg-shared-layout/loader';
|
|
75
|
+
|
|
76
|
+
import { appConfig } from './app/app.config';
|
|
77
|
+
import { App } from './app/app';
|
|
78
|
+
|
|
79
|
+
// MUST run before bootstrapApplication so the browser recognises <weg-footer>
|
|
80
|
+
// by the time Angular's renderer touches the DOM.
|
|
81
|
+
defineCustomElements();
|
|
82
|
+
|
|
83
|
+
bootstrapApplication(App, appConfig).catch((err) => console.error(err));
|
|
34
84
|
```
|
|
35
85
|
|
|
36
|
-
|
|
86
|
+
> If you don't see your footer in the page, 9 times out of 10 it's because this step was skipped. Verify by typing `customElements.get('weg-footer')` in the browser DevTools console — it should return a class, not `undefined`.
|
|
37
87
|
|
|
38
|
-
|
|
39
|
-
|
|
88
|
+
### 3. Provide `HttpClient`
|
|
89
|
+
|
|
90
|
+
You need `HttpClient` to call the layout API. In `src/app/app.config.ts`:
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
|
|
94
|
+
import { provideHttpClient } from '@angular/common/http';
|
|
95
|
+
import { provideRouter } from '@angular/router';
|
|
96
|
+
|
|
97
|
+
import { routes } from './app.routes';
|
|
98
|
+
|
|
99
|
+
export const appConfig: ApplicationConfig = {
|
|
100
|
+
providers: [
|
|
101
|
+
provideBrowserGlobalErrorListeners(),
|
|
102
|
+
provideRouter(routes),
|
|
103
|
+
provideHttpClient(),
|
|
104
|
+
],
|
|
105
|
+
};
|
|
40
106
|
```
|
|
41
107
|
|
|
42
|
-
|
|
108
|
+
### 4. Tell Angular to allow unknown elements
|
|
109
|
+
|
|
110
|
+
Without this, Angular's template compiler throws:
|
|
43
111
|
|
|
44
|
-
|
|
112
|
+
> `'weg-footer' is not a known element: ... If 'weg-footer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@Component.schemas' of this component to suppress this message.`
|
|
45
113
|
|
|
46
|
-
|
|
114
|
+
In **standalone components** (default in Angular 17+), add `schemas: [CUSTOM_ELEMENTS_SCHEMA]` to the `@Component` decorator of **every component that uses `<weg-footer>` in its template**. Easiest is to add it to your root `App` component:
|
|
47
115
|
|
|
48
|
-
|
|
116
|
+
```ts
|
|
117
|
+
// src/app/app.ts
|
|
118
|
+
import { Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit, signal } from '@angular/core';
|
|
119
|
+
import { HttpClient } from '@angular/common/http';
|
|
120
|
+
import { RouterOutlet } from '@angular/router';
|
|
49
121
|
|
|
50
|
-
|
|
122
|
+
const LAYOUT_API = 'https://weg-payload-test.vercel.app/api/layout';
|
|
51
123
|
|
|
52
|
-
|
|
124
|
+
@Component({
|
|
125
|
+
selector: 'app-root',
|
|
126
|
+
imports: [RouterOutlet],
|
|
127
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
128
|
+
templateUrl: './app.html',
|
|
129
|
+
styleUrl: './app.css',
|
|
130
|
+
})
|
|
131
|
+
export class App implements OnInit {
|
|
132
|
+
protected readonly layoutData = signal<unknown>(null);
|
|
53
133
|
|
|
54
|
-
|
|
134
|
+
private readonly http = inject(HttpClient);
|
|
55
135
|
|
|
56
|
-
|
|
136
|
+
ngOnInit(): void {
|
|
137
|
+
this.http.get(LAYOUT_API).subscribe({
|
|
138
|
+
next: (data) => this.layoutData.set(data),
|
|
139
|
+
error: (err) => console.error('Failed to load layout data', err),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
57
144
|
|
|
58
|
-
|
|
145
|
+
> `CUSTOM_ELEMENTS_SCHEMA` is **per-component** in standalone Angular. If you use `<weg-footer>` inside a child component's template, that child must declare `schemas: [CUSTOM_ELEMENTS_SCHEMA]` too. It does **not** cascade through `<router-outlet />`.
|
|
59
146
|
|
|
60
|
-
|
|
147
|
+
### 5. Pass the data into `<weg-footer>` via the `[data]` binding
|
|
61
148
|
|
|
62
|
-
|
|
149
|
+
In `src/app/app.html`:
|
|
63
150
|
|
|
64
151
|
```html
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
https://unpkg.com/foobar-design-system@0.0.1/dist/foobar-design-system/foobar-design-system.esm.js
|
|
69
|
-
-->
|
|
70
|
-
<my-component first="Stencil" middle="'Don't call me a framework'" last="JS"></my-component>
|
|
152
|
+
<router-outlet />
|
|
153
|
+
|
|
154
|
+
<weg-footer [data]="layoutData()"></weg-footer>
|
|
71
155
|
```
|
|
72
156
|
|
|
73
|
-
|
|
157
|
+
That's the whole integration. `<weg-footer>` watches its `data` prop and re-renders when the signal value changes (e.g. when the HTTP response arrives), so an initial `null` is fine — the footer will simply render empty until the data lands.
|
|
74
158
|
|
|
75
|
-
|
|
159
|
+
#### Why `[data]` and not `data-src` or `[attr.data]`
|
|
76
160
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
161
|
+
- `[data]="..."` is Angular's **property binding** — it sets the JS property `data` on the underlying DOM element. Stencil exposes `@Prop()` values as JS properties, so this passes the object straight through. **This is what you want.**
|
|
162
|
+
- `[attr.data]="..."` would set an HTML attribute, which is always a string — Angular would call `JSON.stringify(layoutData)` for you, the component would have to parse it back, and you'd lose type fidelity. Avoid unless you have a reason.
|
|
163
|
+
- Plain `data="..."` only works for a static string literal and would have the same parsing cost — fine for testing, not for real data.
|
|
80
164
|
|
|
81
|
-
|
|
165
|
+
### 6. Verify it works
|
|
82
166
|
|
|
83
|
-
|
|
167
|
+
After running `ng serve`, open the page and check:
|
|
84
168
|
|
|
85
|
-
|
|
169
|
+
1. The dark footer bar renders at the bottom of the page.
|
|
170
|
+
2. DevTools → Network tab shows a `200 OK` to `https://weg-payload-test.vercel.app/api/layout`.
|
|
171
|
+
3. DevTools → Elements → click `<weg-footer>` → in the Console, type `$0.data` — you should see the JSON object you fetched.
|
|
172
|
+
4. Expand `<weg-footer>` in the Elements panel — you should see a `#shadow-root (open)` containing the actual `<footer>` markup.
|
|
86
173
|
|
|
87
|
-
|
|
174
|
+
### Troubleshooting
|
|
88
175
|
|
|
89
|
-
|
|
176
|
+
| Symptom | Cause / fix |
|
|
177
|
+
| --- | --- |
|
|
178
|
+
| `'weg-footer' is not a known element` build error | Add `schemas: [CUSTOM_ELEMENTS_SCHEMA]` to the `@Component` decorator of the component whose template uses `<weg-footer>`. |
|
|
179
|
+
| Element renders as plain inline text / empty box | `defineCustomElements()` was never called. Add it to `main.ts` **before** `bootstrapApplication`. |
|
|
180
|
+
| Footer is in the DOM but blank | The HTTP request failed or returned the wrong shape. Check DevTools → Network → confirm the response matches the [API shape](#layout-api). Also inspect `$0.data` in the console to confirm the binding made it onto the element. |
|
|
181
|
+
| `NullInjectorError: No provider for HttpClient` | You forgot `provideHttpClient()` in `app.config.ts`. |
|
|
182
|
+
| CORS error in the console | The API host must allow your origin. Either fix CORS on the backend, or proxy through Angular's dev proxy (`proxy.conf.json`) so the call becomes same-origin. |
|
|
183
|
+
| Footer doesn't update after data changes | Make sure you're using `[data]="layoutData()"` with a signal (or `[data]="layoutData$ | async"` with an Observable) so Angular pushes new values into the element. |
|
|
184
|
+
| Works locally, fails in SSR (`document is not defined`) | `defineCustomElements()` touches `window` / `customElements`. Wrap in `if (typeof window !== 'undefined') { ... }` or use `isPlatformBrowser(platformId)` in `main.ts`. |
|
|
185
|
+
| TypeScript: `Property 'weg-footer' does not exist on type 'HTMLElementTagNameMap'` | See the typings section below. |
|
|
90
186
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
187
|
+
### TypeScript typings (Angular)
|
|
188
|
+
|
|
189
|
+
If your editor / TS service complains about the unknown element or the `[data]` binding, add this to `src/global.d.ts` (creating the file if needed) and make sure it's included by `tsconfig.json`:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
/// <reference types="weg-shared-layout/dist/types/components" />
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Legacy: using with `NgModule`
|
|
196
|
+
|
|
197
|
+
If your app is still using `NgModule` (pre-Angular 17 default), add `CUSTOM_ELEMENTS_SCHEMA` once at the module level instead of per component:
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
// src/app/app.module.ts
|
|
201
|
+
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
|
202
|
+
import { HttpClientModule } from '@angular/common/http';
|
|
107
203
|
|
|
108
|
-
|
|
204
|
+
@NgModule({
|
|
205
|
+
imports: [HttpClientModule /* ... */],
|
|
206
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
207
|
+
})
|
|
208
|
+
export class AppModule {}
|
|
109
209
|
```
|
|
110
210
|
|
|
111
|
-
|
|
211
|
+
`defineCustomElements()` in `main.ts` is still required either way. Inject `HttpClient` in your component the same way as the standalone example above.
|
|
112
212
|
|
|
113
213
|
## Using in React
|
|
114
214
|
|
|
@@ -134,70 +234,66 @@ Or:
|
|
|
134
234
|
import 'weg-shared-layout';
|
|
135
235
|
```
|
|
136
236
|
|
|
137
|
-
|
|
237
|
+
Then fetch the data in your component and pass it in via a ref (because the `data` prop is an object, not a string attribute):
|
|
138
238
|
|
|
139
|
-
|
|
239
|
+
```tsx
|
|
240
|
+
import { useEffect, useRef, useState } from 'react';
|
|
241
|
+
import 'weg-shared-layout/weg-footer';
|
|
140
242
|
|
|
141
|
-
|
|
243
|
+
const LAYOUT_API = 'https://weg-payload-test.vercel.app/api/layout';
|
|
142
244
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
245
|
+
export function SiteFooter() {
|
|
246
|
+
const ref = useRef<HTMLElement>(null);
|
|
247
|
+
const [layout, setLayout] = useState<unknown>(null);
|
|
248
|
+
|
|
249
|
+
useEffect(() => {
|
|
250
|
+
fetch(LAYOUT_API).then((r) => r.json()).then(setLayout);
|
|
251
|
+
}, []);
|
|
252
|
+
|
|
253
|
+
useEffect(() => {
|
|
254
|
+
if (ref.current) (ref.current as any).data = layout;
|
|
255
|
+
}, [layout]);
|
|
146
256
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
export function WegFooterClient() {
|
|
150
|
-
return (
|
|
151
|
-
<weg-footer
|
|
152
|
-
variant="standard"
|
|
153
|
-
company-name="WEG"
|
|
154
|
-
company-number="12345678"
|
|
155
|
-
social-links-src="/assets/footer-social-links.json"
|
|
156
|
-
standard-links-src="/assets/footer-standard-links.json"
|
|
157
|
-
/>
|
|
158
|
-
);
|
|
257
|
+
return <weg-footer ref={ref} />;
|
|
159
258
|
}
|
|
160
259
|
```
|
|
161
260
|
|
|
162
|
-
|
|
261
|
+
> React (pre-19) sets unknown JSX attributes as HTML attributes, which would stringify your object. Assigning via a ref guarantees you set the JS property. React 19+ handles this correctly without the ref dance.
|
|
163
262
|
|
|
164
|
-
|
|
165
|
-
import 'weg-shared-layout/weg-footer';
|
|
263
|
+
### Next.js (App Router) note
|
|
166
264
|
|
|
167
|
-
|
|
168
|
-
return (
|
|
169
|
-
<weg-footer
|
|
170
|
-
variant="standard"
|
|
171
|
-
company-name="WEG"
|
|
172
|
-
company-number="12345678"
|
|
173
|
-
social-links-src="/assets/footer-social-links.json"
|
|
174
|
-
standard-links-src="/assets/footer-standard-links.json"
|
|
175
|
-
/>
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
```
|
|
265
|
+
Stencil custom elements must be registered **in the browser**. In Next.js `app/` (App Router), don't import/register Stencil components from a Server Component.
|
|
179
266
|
|
|
180
|
-
|
|
267
|
+
Instead, register them in a Client Component, for example:
|
|
181
268
|
|
|
182
269
|
```tsx
|
|
270
|
+
// app/components/SiteFooter.tsx
|
|
271
|
+
"use client";
|
|
272
|
+
|
|
273
|
+
import { useEffect, useRef, useState } from 'react';
|
|
183
274
|
import 'weg-shared-layout/weg-footer';
|
|
184
275
|
|
|
185
|
-
export function
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
276
|
+
export function SiteFooter() {
|
|
277
|
+
const ref = useRef<HTMLElement>(null);
|
|
278
|
+
const [layout, setLayout] = useState<unknown>(null);
|
|
279
|
+
|
|
280
|
+
useEffect(() => {
|
|
281
|
+
fetch('/api/layout').then((r) => r.json()).then(setLayout);
|
|
282
|
+
}, []);
|
|
283
|
+
|
|
284
|
+
useEffect(() => {
|
|
285
|
+
if (ref.current) (ref.current as any).data = layout;
|
|
286
|
+
}, [layout]);
|
|
287
|
+
|
|
288
|
+
return <weg-footer ref={ref} />;
|
|
195
289
|
}
|
|
196
290
|
```
|
|
197
291
|
|
|
292
|
+
(You can also fetch in a Server Component and pass `layout` down as a prop to the Client Component — but the actual `data` assignment still has to happen in the browser.)
|
|
293
|
+
|
|
198
294
|
### React TypeScript typings
|
|
199
295
|
|
|
200
|
-
Stencil generates `components.d.ts
|
|
296
|
+
Stencil generates `components.d.ts`, but React doesn't pick up custom element typings automatically. Add a `global.d.ts` that references the generated types:
|
|
201
297
|
|
|
202
298
|
```ts
|
|
203
299
|
/// <reference types="weg-shared-layout/dist/types/components" />
|
|
@@ -205,58 +301,28 @@ Stencil generates `components.d.ts` in this repo, but React does not automatical
|
|
|
205
301
|
|
|
206
302
|
If your app still complains about JSX intrinsic elements, you can also augment `JSX.IntrinsicElements` in that same file (varies by React/TS setup).
|
|
207
303
|
|
|
208
|
-
##
|
|
209
|
-
|
|
210
|
-
Install:
|
|
211
|
-
|
|
212
|
-
```bash
|
|
213
|
-
npm i weg-shared-layout
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
Register custom elements (recommended in `main.ts`):
|
|
217
|
-
|
|
218
|
-
```ts
|
|
219
|
-
import { defineCustomElements } from 'weg-shared-layout/loader';
|
|
220
|
-
|
|
221
|
-
defineCustomElements();
|
|
222
|
-
```
|
|
304
|
+
## Plain HTML / vanilla JS
|
|
223
305
|
|
|
224
|
-
|
|
306
|
+
For a quick smoke test outside of a framework, fetch the JSON and assign it to the element's `data` property:
|
|
225
307
|
|
|
226
|
-
```
|
|
227
|
-
|
|
308
|
+
```html
|
|
309
|
+
<weg-footer id="footer"></weg-footer>
|
|
228
310
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
export class AppModule {}
|
|
311
|
+
<script type="module">
|
|
312
|
+
const res = await fetch('https://weg-payload-test.vercel.app/api/layout');
|
|
313
|
+
document.getElementById('footer').data = await res.json();
|
|
314
|
+
</script>
|
|
234
315
|
```
|
|
235
316
|
|
|
236
|
-
|
|
317
|
+
You can also pass the JSON as a string attribute — useful for SSR or static HTML where you don't want a runtime fetch:
|
|
237
318
|
|
|
238
319
|
```html
|
|
239
|
-
<weg-footer
|
|
240
|
-
variant="standard"
|
|
241
|
-
company-name="WEG"
|
|
242
|
-
company-number="12345678"
|
|
243
|
-
social-links-src="/assets/footer-social-links.json"
|
|
244
|
-
standard-links-src="/assets/footer-standard-links.json"
|
|
245
|
-
></weg-footer>
|
|
320
|
+
<weg-footer data='{"footer":{"social":[],"standardLinks":[],"credits":"","copyright":"Copyright © WEG."}}'></weg-footer>
|
|
246
321
|
```
|
|
247
322
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
```html
|
|
251
|
-
<weg-footer
|
|
252
|
-
variant="additional"
|
|
253
|
-
company-name="WEG"
|
|
254
|
-
company-number="12345678"
|
|
255
|
-
social-links-src="/assets/footer-social-links.json"
|
|
256
|
-
additional-groups-src="/assets/footer-additional-groups.json"
|
|
257
|
-
></weg-footer>
|
|
258
|
-
```
|
|
323
|
+
## CORS
|
|
259
324
|
|
|
260
|
-
|
|
325
|
+
Because the host app calls the API directly, **the API must respond with `Access-Control-Allow-Origin` headers** that include your app's origin. If you hit a CORS error in the browser console, either:
|
|
261
326
|
|
|
262
|
-
|
|
327
|
+
- Fix CORS on the API host, **or**
|
|
328
|
+
- Proxy the call through your own host. Angular: configure `proxy.conf.json` so `/api/layout` is rewritten to the production URL. Next.js: add a route handler that re-fetches and returns the JSON.
|