weg-shared-layout 0.0.23 → 0.0.25

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 (57) hide show
  1. package/LICENSE +21 -21
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/weg-footer_2.cjs.entry.js +307 -219
  4. package/dist/cjs/weg-shared-layout.cjs.js +1 -1
  5. package/dist/collection/collection-manifest.json +0 -1
  6. package/dist/collection/components/weg-footer/icons/instagram.svg +5 -5
  7. package/dist/collection/components/weg-footer/icons/linkedin.svg +3 -3
  8. package/dist/collection/components/weg-footer/icons/tiktok.svg +3 -3
  9. package/dist/collection/components/weg-footer/icons/youtube.svg +4 -4
  10. package/dist/collection/components/weg-footer/weg-footer.css +270 -201
  11. package/dist/collection/components/weg-footer/weg-footer.js +22 -26
  12. package/dist/collection/components/weg-header/weg-header.css +474 -365
  13. package/dist/collection/components/weg-header/weg-header.js +226 -166
  14. package/dist/collection/constants/breakpoints.js +6 -0
  15. package/dist/collection/styles/shared.css +72 -78
  16. package/dist/collection/utils/layout.js +57 -9
  17. package/dist/components/p-BnMIy-A5.js +1 -0
  18. package/dist/components/weg-footer.js +1 -1
  19. package/dist/components/weg-header.js +1 -1
  20. package/dist/esm/loader.js +1 -1
  21. package/dist/esm/weg-footer_2.entry.js +307 -219
  22. package/dist/esm/weg-shared-layout.js +1 -1
  23. package/dist/types/components/weg-footer/weg-footer.d.ts +2 -2
  24. package/dist/types/components/weg-header/weg-header.d.ts +32 -16
  25. package/dist/types/components.d.ts +6 -48
  26. package/dist/types/constants/breakpoints.d.ts +6 -0
  27. package/dist/types/types/layout-data.d.ts +13 -27
  28. package/dist/types/utils/layout.d.ts +9 -1
  29. package/dist/weg-shared-layout/p-d74a58cf.entry.js +1 -0
  30. package/dist/weg-shared-layout/weg-shared-layout.esm.js +1 -1
  31. package/docs/angular-integration-guide.md +1004 -0
  32. package/docs/angular.md +229 -138
  33. package/docs/nextjs.md +306 -305
  34. package/docs/publishing.md +48 -48
  35. package/docs/react.md +261 -261
  36. package/docs/vanilla.md +138 -140
  37. package/package.json +12 -8
  38. package/readme.md +82 -107
  39. package/src/assets/dummy-data.json +137 -63
  40. package/src/constants/breakpoints.ts +7 -0
  41. package/dist/cjs/my-component.cjs.entry.js +0 -33
  42. package/dist/collection/components/my-component/my-component.css +0 -3
  43. package/dist/collection/components/my-component/my-component.js +0 -95
  44. package/dist/collection/components/weg-header/signed-in-layout.js +0 -13
  45. package/dist/collection/constants/weg-urls.js +0 -18
  46. package/dist/components/my-component.d.ts +0 -11
  47. package/dist/components/my-component.js +0 -1
  48. package/dist/components/p-DbIEJ3IT.js +0 -1
  49. package/dist/esm/my-component.entry.js +0 -31
  50. package/dist/types/components/my-component/my-component.d.ts +0 -16
  51. package/dist/types/components/weg-header/signed-in-layout.d.ts +0 -18
  52. package/dist/types/constants/weg-urls.d.ts +0 -18
  53. package/dist/weg-shared-layout/p-80fa529c.entry.js +0 -1
  54. package/dist/weg-shared-layout/p-d61033bd.entry.js +0 -1
  55. package/src/constants/weg-urls.ts +0 -23
  56. /package/dist/types/Users/{tan/Documents/code → rakin/Documents/WEG/repos}/weg-shared-layout/.stencil/test-utils/axe.d.ts +0 -0
  57. /package/dist/types/Users/{tan/Documents/code → rakin/Documents/WEG/repos}/weg-shared-layout/.stencil/test-utils/viewport.d.ts +0 -0
package/docs/nextjs.md CHANGED
@@ -1,305 +1,306 @@
1
- # Next.js (App Router)
2
-
3
- Guide for **Next.js 13+ App Router** (`app/` directory). For Vite/CRA-style client-only React, see **[React SPA](./react.md)**.
4
-
5
- ## Components
6
-
7
- | Tag | Purpose |
8
- | --- | --- |
9
- | `<weg-header>` | Site header — bundled logo, CMS nav (signed out), built-in nav (signed in), Sign in / Manage Account / Sign out |
10
- | `<weg-footer>` | Site footer — social, columns, legal text |
11
-
12
- Both accept **`layout`** (JSON string recommended in Next). `<weg-header>` also accepts **`signed-in`**, **`user-name`**, and emits **`wegAuthClick`**.
13
-
14
- ## Why Next.js is different
15
-
16
- | Topic | SPA (React 19) | Next.js App Router |
17
- | --- | --- | --- |
18
- | **Where components run** | Client only | Must be in **Client Components** (`"use client"`) |
19
- | **Server Components** | N/A | Default in `app/` — cannot call `defineCustomElements()` |
20
- | **SSR output** | N/A | Often empty custom-element tags until client hydrates |
21
- | **`layout={object}` on CE** | Works on React 19+ | **Unreliable** — use **`JSON.stringify(layout)`** |
22
- | **Auth state** | `signed-in` prop | Set in client wrapper from session hook / context |
23
-
24
- ## Requirements
25
-
26
- | Requirement | Notes |
27
- | --- | --- |
28
- | **Next.js 13+** | App Router (`app/layout.tsx`) |
29
- | **`transpilePackages`** | Next must compile `weg-shared-layout` |
30
- | **`suppressHydrationWarning`** | Recommended on both tags (SSR placeholder vs client shadow DOM) |
31
-
32
- ## Install
33
-
34
- ```bash
35
- npm i weg-shared-layout
36
- # or
37
- pnpm add weg-shared-layout
38
- ```
39
-
40
- ## 1. Transpile the package
41
-
42
- ```ts
43
- // next.config.ts
44
- import type { NextConfig } from 'next';
45
-
46
- const nextConfig: NextConfig = {
47
- transpilePackages: ['weg-shared-layout'],
48
- };
49
-
50
- export default nextConfig;
51
- ```
52
-
53
- ## 2. Auth constants (host app)
54
-
55
- Keep sign-in/out URLs in your app — not imported from `weg-shared-layout`:
56
-
57
- ```ts
58
- // src/auth.ts
59
- export const HEADER_SIGN_IN = {
60
- label: 'Sign in',
61
- href: 'https://account.warwickemploymentgroup.com/account/login',
62
- };
63
-
64
- export const ACCOUNT_LOGIN_HREF = HEADER_SIGN_IN.href;
65
- ```
66
-
67
- ## 3. Client layout components
68
-
69
- ```tsx
70
- // src/components/layout/Header.tsx
71
- 'use client';
72
-
73
- import { useCallback } from 'react';
74
- import { defineCustomElements } from 'weg-shared-layout/loader';
75
- import { ACCOUNT_LOGIN_HREF, HEADER_SIGN_IN } from '@/auth';
76
- import 'weg-shared-layout/weg-header';
77
-
78
- defineCustomElements();
79
-
80
- type LayoutData = {
81
- header?: {
82
- logoHref?: string;
83
- dropdowns?: { label: string; items: { label: string; href: string }[] }[];
84
- links?: { label: string; href: string }[];
85
- signIn?: { label: string; href: string };
86
- };
87
- };
88
-
89
- export function Header({
90
- layout,
91
- signedIn,
92
- userName,
93
- onSignedInChange,
94
- }: {
95
- layout: LayoutData;
96
- signedIn: boolean;
97
- userName?: string;
98
- onSignedInChange?: (signedIn: boolean) => void;
99
- }) {
100
- const onAuthClick = useCallback(
101
- (event: CustomEvent<{ action: 'sign-in' | 'sign-out' }>) => {
102
- event.preventDefault();
103
-
104
- if (event.detail.action === 'sign-out') {
105
- onSignedInChange?.(false);
106
- window.location.href = ACCOUNT_LOGIN_HREF;
107
- return;
108
- }
109
-
110
- window.location.href = layout.header?.signIn?.href ?? HEADER_SIGN_IN.href;
111
- },
112
- [layout, onSignedInChange],
113
- );
114
-
115
- return (
116
- <weg-header
117
- layout={JSON.stringify(layout)}
118
- signedIn={signedIn}
119
- {...(userName ? { userName } : {})}
120
- suppressHydrationWarning
121
- onWegAuthClick={onAuthClick}
122
- />
123
- );
124
- }
125
- ```
126
-
127
- ```tsx
128
- // src/components/layout/Footer.tsx
129
- 'use client';
130
-
131
- import { defineCustomElements } from 'weg-shared-layout/loader';
132
- import 'weg-shared-layout/weg-footer';
133
-
134
- defineCustomElements();
135
-
136
- export function Footer({ layout }: { layout: unknown }) {
137
- return <weg-footer layout={JSON.stringify(layout)} suppressHydrationWarning />;
138
- }
139
- ```
140
-
141
- ```tsx
142
- // src/components/layout/SiteChrome.tsx — optional wrapper
143
- 'use client';
144
-
145
- import { useState } from 'react';
146
- import { Header } from './Header';
147
- import { Footer } from './Footer';
148
-
149
- export function SiteChrome({
150
- layout,
151
- children,
152
- }: {
153
- layout: unknown;
154
- children: React.ReactNode;
155
- }) {
156
- const [signedIn, setSignedIn] = useState(false);
157
- const userName = signedIn ? 'Alex' : undefined; // from your session
158
-
159
- return (
160
- <>
161
- <Header
162
- layout={layout}
163
- signedIn={signedIn}
164
- userName={userName}
165
- onSignedInChange={setSignedIn}
166
- />
167
- {children}
168
- <Footer layout={layout} />
169
- </>
170
- );
171
- }
172
- ```
173
-
174
- ### Why `JSON.stringify` and `suppressHydrationWarning`
175
-
176
- | Line | Purpose |
177
- | --- | --- |
178
- | `layout={JSON.stringify(layout)}` | Serializable across RSC → client; component parses JSON |
179
- | `suppressHydrationWarning` | Server renders empty tag; client fills shadow DOM |
180
- | `'use client'` | Registration and auth handlers need the browser |
181
-
182
- Do **not** pass `layout={layoutObject}` directly on the custom elements in Next.
183
-
184
- ## 4. Server layout
185
-
186
- ```tsx
187
- // app/layout.tsx (Server Component)
188
- import { SiteChrome } from '@/components/layout/SiteChrome';
189
- import layout from 'weg-shared-layout/dummy-data.json';
190
-
191
- export default function RootLayout({ children }: { children: React.ReactNode }) {
192
- return (
193
- <html lang="en">
194
- <body>
195
- <SiteChrome layout={layout}>{children}</SiteChrome>
196
- </body>
197
- </html>
198
- );
199
- }
200
- ```
201
-
202
- ## 5. Production: fetch layout on the server
203
-
204
- ```tsx
205
- // app/layout.tsx
206
- import { SiteChrome } from '@/components/layout/SiteChrome';
207
-
208
- const LAYOUT_URL = 'https://weg-payload-test.vercel.app/api/layout';
209
-
210
- async function getLayout() {
211
- const res = await fetch(LAYOUT_URL, { next: { revalidate: 60 } });
212
- if (!res.ok) throw new Error('Failed to load layout');
213
- return res.json();
214
- }
215
-
216
- export default async function RootLayout({ children }: { children: React.ReactNode }) {
217
- const layout = await getLayout();
218
-
219
- return (
220
- <html lang="en">
221
- <body>
222
- <SiteChrome layout={layout}>{children}</SiteChrome>
223
- </body>
224
- </html>
225
- );
226
- }
227
- ```
228
-
229
- Pass the plain object into the Client Component; **stringify inside** the header/footer wrappers.
230
-
231
- Wire **`signedIn`** and **`userName`** from your auth provider (session hook / context in a client wrapper).
232
-
233
- ## Header auth reference
234
-
235
- | API | Signed out | Signed in |
236
- | --- | --- | --- |
237
- | `layout.header.dropdowns` / `links` | CMS nav rendered | Ignored — built-in nav used |
238
- | `layout.header.signIn` | Sign in button | Not shown |
239
- | `layout.header.logoHref` | Logo link target | Built-in WEG home URL |
240
- | `signed-in` prop | `false` | `true` — session flag from host app |
241
- | `user-name` prop | — | User's first name on Manage Account |
242
- | `wegAuthClick` event | `'sign-in'` on Sign in click | `'sign-out'` on Sign out click |
243
- | `event.preventDefault()` | Skip default navigation | Skip default redirect |
244
-
245
- **Signed-in nav (built into the component):** Find a job, Dashboard, Manage Account, Sign out.
246
-
247
- The logo **image** is bundled. The logo **link** uses `layout.header.logoHref` when signed out.
248
-
249
- ## Passing `layout` — quick reference
250
-
251
- | Approach | Works in Next? |
252
- | --- | --- |
253
- | `layout={object}` on `<weg-header>` / `<weg-footer>` | **No** |
254
- | `layout={JSON.stringify(obj)}` in client wrapper | **Yes** (recommended) |
255
- | Pass object to `<SiteChrome layout={...} />`, stringify in child | **Yes** |
256
- | `ref` + `el.layout = obj` in `useEffect` | Yes (escape hatch) |
257
-
258
- ## TypeScript
259
-
260
- ```ts
261
- // src/types/weg-shared-layout-jsx.d.ts
262
- import type { JSX as WegSharedLayoutJSX } from 'weg-shared-layout';
263
- import type { DetailedHTMLProps, HTMLAttributes } from 'react';
264
-
265
- declare module 'react' {
266
- namespace JSX {
267
- interface IntrinsicElements extends WegSharedLayoutJSX.IntrinsicElements {
268
- 'weg-header': WegSharedLayoutJSX.IntrinsicElements['weg-header'] &
269
- DetailedHTMLProps<HTMLAttributes<HTMLWegHeaderElement>, HTMLWegHeaderElement>;
270
- 'weg-footer': WegSharedLayoutJSX.IntrinsicElements['weg-footer'] &
271
- DetailedHTMLProps<HTMLAttributes<HTMLWegFooterElement>, HTMLWegFooterElement>;
272
- }
273
- }
274
- }
275
- ```
276
-
277
- ## Troubleshooting
278
-
279
- | Symptom | Likely cause | Fix |
280
- | --- | --- | --- |
281
- | `document is not defined` | Loader in Server Component | Keep registration in `"use client"` files only. |
282
- | Empty after hydration | Object passed to CE without stringify | `JSON.stringify` in client wrapper. |
283
- | Logo missing | Stale package | Logo is inlined in `logo-data.ts`; rebuild / upgrade. |
284
- | Header not clickable | Overlapping page content | `:host` uses `z-index: 20`; upgrade package if missing. |
285
- | Auth not updating | `signed-in` only on server | Manage session in client state / context. |
286
- | Hydration warning | Shadow DOM mismatch | `suppressHydrationWarning` on both tags. |
287
- | Build error | Package not transpiled | `transpilePackages: ['weg-shared-layout']`. |
288
-
289
- ## Integration checklist
290
-
291
- - [ ] `weg-shared-layout` installed
292
- - [ ] `transpilePackages` in `next.config`
293
- - [ ] Client `Header.tsx` / `Footer.tsx` with loader, tag imports, `JSON.stringify`, `suppressHydrationWarning`
294
- - [ ] Auth: `signed-in`, `user-name`, and `wegAuthClick` handler on header
295
- - [ ] Server `layout.tsx` imports client chrome only (no `defineCustomElements` on server)
296
- - [ ] Layout fetched or imported server-side, passed as serializable props
297
- - [ ] TypeScript augmentation for `'weg-header'` and `'weg-footer'`
298
- - [ ] Verified in browser after hydration
299
-
300
- ## See also
301
-
302
- - **[React SPA](./react.md)**
303
- - **[Angular](./angular.md)**
304
- - **[Plain HTML / vanilla JS](./vanilla.md)**
305
- - **[Package readme](../readme.md)**
1
+ # Next.js (App Router)
2
+
3
+ Guide for **Next.js 13+ App Router** (`app/` directory). For Vite/CRA-style client-only React, see **[React SPA](./react.md)**.
4
+
5
+ ## Components
6
+
7
+ | Tag | Purpose |
8
+ | --- | --- |
9
+ | `<weg-header>` | Site header — bundled logo, CMS nav (signed out), built-in nav (signed in), Sign in / Manage Account / Sign out |
10
+ | `<weg-footer>` | Site footer — social, menu, legal text |
11
+
12
+ Both accept **`layout`** (JSON string recommended in Next). `<weg-header>` also accepts **`signed-in`**, **`user-name`**, and emits **`wegAuthClick`**.
13
+
14
+ ## Why Next.js is different
15
+
16
+ | Topic | SPA (React 19) | Next.js App Router |
17
+ | --- | --- | --- |
18
+ | **Where components run** | Client only | Must be in **Client Components** (`"use client"`) |
19
+ | **Server Components** | N/A | Default in `app/` — cannot call `defineCustomElements()` |
20
+ | **SSR output** | N/A | Often empty custom-element tags until client hydrates |
21
+ | **`layout={object}` on CE** | Works on React 19+ | **Unreliable** — use **`JSON.stringify(layout)`** |
22
+ | **Auth state** | `signed-in` prop | Set in client wrapper from session hook / context |
23
+
24
+ ## Requirements
25
+
26
+ | Requirement | Notes |
27
+ | --- | --- |
28
+ | **Next.js 13+** | App Router (`app/layout.tsx`) |
29
+ | **`transpilePackages`** | Next must compile `weg-shared-layout` |
30
+ | **`suppressHydrationWarning`** | Recommended on both tags (SSR placeholder vs client shadow DOM) |
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ npm i weg-shared-layout
36
+ # or
37
+ pnpm add weg-shared-layout
38
+ ```
39
+
40
+ ## 1. Transpile the package
41
+
42
+ ```ts
43
+ // next.config.ts
44
+ import type { NextConfig } from 'next';
45
+
46
+ const nextConfig: NextConfig = {
47
+ transpilePackages: ['weg-shared-layout'],
48
+ };
49
+
50
+ export default nextConfig;
51
+ ```
52
+
53
+ ## 2. Auth constants (host app)
54
+
55
+ Keep sign-in/out URLs in your app — not imported from `weg-shared-layout`:
56
+
57
+ ```ts
58
+ // src/auth.ts
59
+ export const HEADER_SIGN_IN = {
60
+ label: 'Sign in',
61
+ href: 'https://account.warwickemploymentgroup.com/account/login',
62
+ };
63
+
64
+ export const ACCOUNT_LOGIN_HREF = HEADER_SIGN_IN.href;
65
+ ```
66
+
67
+ ## 3. Client layout components
68
+
69
+ ```tsx
70
+ // src/components/layout/Header.tsx
71
+ 'use client';
72
+
73
+ import { useCallback } from 'react';
74
+ import { defineCustomElements } from 'weg-shared-layout/loader';
75
+ import { ACCOUNT_LOGIN_HREF, HEADER_SIGN_IN } from '@/auth';
76
+ import 'weg-shared-layout/weg-header';
77
+
78
+ defineCustomElements();
79
+
80
+ type LayoutData = {
81
+ header?: {
82
+ logoSrc?: string;
83
+ menu?: {
84
+ label: string;
85
+ href?: string;
86
+ items?: { label: string; href: string }[];
87
+ }[];
88
+ };
89
+ };
90
+
91
+ export function Header({
92
+ layout,
93
+ signedIn,
94
+ userName,
95
+ onSignedInChange,
96
+ }: {
97
+ layout: LayoutData;
98
+ signedIn: boolean;
99
+ userName?: string;
100
+ onSignedInChange?: (signedIn: boolean) => void;
101
+ }) {
102
+ const onAuthClick = useCallback(
103
+ (event: CustomEvent<{ action: 'sign-in' | 'sign-out' }>) => {
104
+ event.preventDefault();
105
+
106
+ if (event.detail.action === 'sign-out') {
107
+ onSignedInChange?.(false);
108
+ window.location.href = ACCOUNT_LOGIN_HREF;
109
+ return;
110
+ }
111
+
112
+ window.location.href = HEADER_SIGN_IN.href;
113
+ },
114
+ [layout, onSignedInChange],
115
+ );
116
+
117
+ return (
118
+ <weg-header
119
+ layout={JSON.stringify(layout)}
120
+ signedIn={signedIn}
121
+ {...(userName ? { userName } : {})}
122
+ suppressHydrationWarning
123
+ onWegAuthClick={onAuthClick}
124
+ />
125
+ );
126
+ }
127
+ ```
128
+
129
+ ```tsx
130
+ // src/components/layout/Footer.tsx
131
+ 'use client';
132
+
133
+ import { defineCustomElements } from 'weg-shared-layout/loader';
134
+ import 'weg-shared-layout/weg-footer';
135
+
136
+ defineCustomElements();
137
+
138
+ export function Footer({ layout }: { layout: unknown }) {
139
+ return <weg-footer layout={JSON.stringify(layout)} suppressHydrationWarning />;
140
+ }
141
+ ```
142
+
143
+ ```tsx
144
+ // src/components/layout/SiteChrome.tsx — optional wrapper
145
+ 'use client';
146
+
147
+ import { useState } from 'react';
148
+ import { Header } from './Header';
149
+ import { Footer } from './Footer';
150
+
151
+ export function SiteChrome({
152
+ layout,
153
+ children,
154
+ }: {
155
+ layout: unknown;
156
+ children: React.ReactNode;
157
+ }) {
158
+ const [signedIn, setSignedIn] = useState(false);
159
+ const userName = signedIn ? 'Alex' : undefined; // from your session
160
+
161
+ return (
162
+ <>
163
+ <Header
164
+ layout={layout}
165
+ signedIn={signedIn}
166
+ userName={userName}
167
+ onSignedInChange={setSignedIn}
168
+ />
169
+ {children}
170
+ <Footer layout={layout} />
171
+ </>
172
+ );
173
+ }
174
+ ```
175
+
176
+ ### Why `JSON.stringify` and `suppressHydrationWarning`
177
+
178
+ | Line | Purpose |
179
+ | --- | --- |
180
+ | `layout={JSON.stringify(layout)}` | Serializable across RSC → client; component parses JSON |
181
+ | `suppressHydrationWarning` | Server renders empty tag; client fills shadow DOM |
182
+ | `'use client'` | Registration and auth handlers need the browser |
183
+
184
+ Do **not** pass `layout={layoutObject}` directly on the custom elements in Next.
185
+
186
+ ## 4. Server layout
187
+
188
+ ```tsx
189
+ // app/layout.tsx (Server Component)
190
+ import { SiteChrome } from '@/components/layout/SiteChrome';
191
+ import layout from 'weg-shared-layout/dummy-data.json';
192
+
193
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
194
+ return (
195
+ <html lang="en">
196
+ <body>
197
+ <SiteChrome layout={layout}>{children}</SiteChrome>
198
+ </body>
199
+ </html>
200
+ );
201
+ }
202
+ ```
203
+
204
+ ## 5. Production: fetch layout on the server
205
+
206
+ ```tsx
207
+ // app/layout.tsx
208
+ import { SiteChrome } from '@/components/layout/SiteChrome';
209
+
210
+ const LAYOUT_URL = 'https://weg-payload-test.vercel.app/api/layout';
211
+
212
+ async function getLayout() {
213
+ const res = await fetch(LAYOUT_URL, { next: { revalidate: 60 } });
214
+ if (!res.ok) throw new Error('Failed to load layout');
215
+ return res.json();
216
+ }
217
+
218
+ export default async function RootLayout({ children }: { children: React.ReactNode }) {
219
+ const layout = await getLayout();
220
+
221
+ return (
222
+ <html lang="en">
223
+ <body>
224
+ <SiteChrome layout={layout}>{children}</SiteChrome>
225
+ </body>
226
+ </html>
227
+ );
228
+ }
229
+ ```
230
+
231
+ Pass the plain object into the Client Component; **stringify inside** the header/footer wrappers.
232
+
233
+ Wire **`signedIn`** and **`userName`** from your auth provider (session hook / context in a client wrapper).
234
+
235
+ ## Header auth reference
236
+
237
+ | API | Signed out | Signed in |
238
+ | --- | --- | --- |
239
+ | `layout.header.menu` | CMS nav rendered (groups + flat links incl. Sign in) | Ignored — built-in nav used |
240
+ | `layout.header.logoSrc` | Logo image URL (bundled if omitted) | Built-in bundled logo |
241
+ | `signed-in` prop | `false` | `true` — session flag from host app |
242
+ | `user-name` prop | — | User's first name on Manage Account |
243
+ | `wegAuthClick` event | `'sign-in'` on Sign in click | `'sign-out'` on Sign out click |
244
+ | `event.preventDefault()` | Skip default navigation | Skip default redirect |
245
+
246
+ **Signed-in nav (built into the component):** Find a job, Dashboard, Manage Account, Sign out.
247
+
248
+ The logo **image** uses `layout.header.logoSrc` when signed out (bundled if omitted). The logo **link** always goes to WEG home.
249
+
250
+ ## Passing `layout` — quick reference
251
+
252
+ | Approach | Works in Next? |
253
+ | --- | --- |
254
+ | `layout={object}` on `<weg-header>` / `<weg-footer>` | **No** |
255
+ | `layout={JSON.stringify(obj)}` in client wrapper | **Yes** (recommended) |
256
+ | Pass object to `<SiteChrome layout={...} />`, stringify in child | **Yes** |
257
+ | `ref` + `el.layout = obj` in `useEffect` | Yes (escape hatch) |
258
+
259
+ ## TypeScript
260
+
261
+ ```ts
262
+ // src/types/weg-shared-layout-jsx.d.ts
263
+ import type { JSX as WegSharedLayoutJSX } from 'weg-shared-layout';
264
+ import type { DetailedHTMLProps, HTMLAttributes } from 'react';
265
+
266
+ declare module 'react' {
267
+ namespace JSX {
268
+ interface IntrinsicElements extends WegSharedLayoutJSX.IntrinsicElements {
269
+ 'weg-header': WegSharedLayoutJSX.IntrinsicElements['weg-header'] &
270
+ DetailedHTMLProps<HTMLAttributes<HTMLWegHeaderElement>, HTMLWegHeaderElement>;
271
+ 'weg-footer': WegSharedLayoutJSX.IntrinsicElements['weg-footer'] &
272
+ DetailedHTMLProps<HTMLAttributes<HTMLWegFooterElement>, HTMLWegFooterElement>;
273
+ }
274
+ }
275
+ }
276
+ ```
277
+
278
+ ## Troubleshooting
279
+
280
+ | Symptom | Likely cause | Fix |
281
+ | --- | --- | --- |
282
+ | `document is not defined` | Loader in Server Component | Keep registration in `"use client"` files only. |
283
+ | Empty after hydration | Object passed to CE without stringify | `JSON.stringify` in client wrapper. |
284
+ | Logo missing | Stale package | Logo is inlined in `logo-data.ts`; rebuild / upgrade. |
285
+ | Header not clickable | Overlapping page content | `:host` uses `z-index: 20`; upgrade package if missing. |
286
+ | Auth not updating | `signed-in` only on server | Manage session in client state / context. |
287
+ | Hydration warning | Shadow DOM mismatch | `suppressHydrationWarning` on both tags. |
288
+ | Build error | Package not transpiled | `transpilePackages: ['weg-shared-layout']`. |
289
+
290
+ ## Integration checklist
291
+
292
+ - [ ] `weg-shared-layout` installed
293
+ - [ ] `transpilePackages` in `next.config`
294
+ - [ ] Client `Header.tsx` / `Footer.tsx` with loader, tag imports, `JSON.stringify`, `suppressHydrationWarning`
295
+ - [ ] Auth: `signed-in`, `user-name`, and `wegAuthClick` handler on header
296
+ - [ ] Server `layout.tsx` imports client chrome only (no `defineCustomElements` on server)
297
+ - [ ] Layout fetched or imported server-side, passed as serializable props
298
+ - [ ] TypeScript augmentation for `'weg-header'` and `'weg-footer'`
299
+ - [ ] Verified in browser after hydration
300
+
301
+ ## See also
302
+
303
+ - **[React SPA](./react.md)**
304
+ - **[Angular](./angular.md)**
305
+ - **[Plain HTML / vanilla JS](./vanilla.md)**
306
+ - **[Package readme](../readme.md)**