@strategicnerds/slide-nerds 0.1.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 (101) hide show
  1. package/dist/cli/commands/analytics.d.ts +6 -0
  2. package/dist/cli/commands/analytics.d.ts.map +1 -0
  3. package/dist/cli/commands/analytics.js +44 -0
  4. package/dist/cli/commands/analytics.js.map +1 -0
  5. package/dist/cli/commands/create.d.ts +4 -0
  6. package/dist/cli/commands/create.d.ts.map +1 -0
  7. package/dist/cli/commands/create.js +87 -0
  8. package/dist/cli/commands/create.js.map +1 -0
  9. package/dist/cli/commands/export.d.ts +6 -0
  10. package/dist/cli/commands/export.d.ts.map +1 -0
  11. package/dist/cli/commands/export.js +109 -0
  12. package/dist/cli/commands/export.js.map +1 -0
  13. package/dist/cli/index.d.ts +3 -0
  14. package/dist/cli/index.d.ts.map +1 -0
  15. package/dist/cli/index.js +12 -0
  16. package/dist/cli/index.js.map +1 -0
  17. package/dist/cli/template-path.d.ts +4 -0
  18. package/dist/cli/template-path.d.ts.map +1 -0
  19. package/dist/cli/template-path.js +13 -0
  20. package/dist/cli/template-path.js.map +1 -0
  21. package/dist/runtime/export-api.d.ts +15 -0
  22. package/dist/runtime/export-api.d.ts.map +1 -0
  23. package/dist/runtime/export-api.js +21 -0
  24. package/dist/runtime/export-api.js.map +1 -0
  25. package/dist/runtime/index.d.ts +12 -0
  26. package/dist/runtime/index.d.ts.map +1 -0
  27. package/dist/runtime/index.js +8 -0
  28. package/dist/runtime/index.js.map +1 -0
  29. package/dist/runtime/light-table.d.ts +8 -0
  30. package/dist/runtime/light-table.d.ts.map +1 -0
  31. package/dist/runtime/light-table.js +104 -0
  32. package/dist/runtime/light-table.js.map +1 -0
  33. package/dist/runtime/presenter-view.d.ts +7 -0
  34. package/dist/runtime/presenter-view.d.ts.map +1 -0
  35. package/dist/runtime/presenter-view.js +62 -0
  36. package/dist/runtime/presenter-view.js.map +1 -0
  37. package/dist/runtime/slide-context.d.ts +16 -0
  38. package/dist/runtime/slide-context.d.ts.map +1 -0
  39. package/dist/runtime/slide-context.js +18 -0
  40. package/dist/runtime/slide-context.js.map +1 -0
  41. package/dist/runtime/slide-controls.d.ts +3 -0
  42. package/dist/runtime/slide-controls.d.ts.map +1 -0
  43. package/dist/runtime/slide-controls.js +177 -0
  44. package/dist/runtime/slide-controls.js.map +1 -0
  45. package/dist/runtime/slide-dom.d.ts +17 -0
  46. package/dist/runtime/slide-dom.d.ts.map +1 -0
  47. package/dist/runtime/slide-dom.js +89 -0
  48. package/dist/runtime/slide-dom.js.map +1 -0
  49. package/dist/runtime/slide-runtime.d.ts +7 -0
  50. package/dist/runtime/slide-runtime.d.ts.map +1 -0
  51. package/dist/runtime/slide-runtime.js +125 -0
  52. package/dist/runtime/slide-runtime.js.map +1 -0
  53. package/dist/runtime/slide-shape.d.ts +21 -0
  54. package/dist/runtime/slide-shape.d.ts.map +1 -0
  55. package/dist/runtime/slide-shape.js +115 -0
  56. package/dist/runtime/slide-shape.js.map +1 -0
  57. package/dist/runtime/types.d.ts +150 -0
  58. package/dist/runtime/types.d.ts.map +1 -0
  59. package/dist/runtime/types.js +38 -0
  60. package/dist/runtime/types.js.map +1 -0
  61. package/dist/runtime/use-presenter-mode.d.ts +14 -0
  62. package/dist/runtime/use-presenter-mode.d.ts.map +1 -0
  63. package/dist/runtime/use-presenter-mode.js +52 -0
  64. package/dist/runtime/use-presenter-mode.js.map +1 -0
  65. package/dist/runtime/use-slide-navigation.d.ts +13 -0
  66. package/dist/runtime/use-slide-navigation.d.ts.map +1 -0
  67. package/dist/runtime/use-slide-navigation.js +230 -0
  68. package/dist/runtime/use-slide-navigation.js.map +1 -0
  69. package/package.json +64 -0
  70. package/skills/accessibility/SKILL.md +236 -0
  71. package/skills/advanced-layouts/SKILL.md +429 -0
  72. package/skills/analytics/SKILL.md +97 -0
  73. package/skills/animation/SKILL.md +364 -0
  74. package/skills/brand/SKILL.md +200 -0
  75. package/skills/data-visualization/SKILL.md +533 -0
  76. package/skills/deck-templates/SKILL.md +93 -0
  77. package/skills/diagrams/SKILL.md +395 -0
  78. package/skills/export/SKILL.md +119 -0
  79. package/skills/interactive/SKILL.md +292 -0
  80. package/skills/layout/SKILL.md +178 -0
  81. package/skills/narrative-frameworks/SKILL.md +250 -0
  82. package/skills/react-component-embeds/SKILL.md +73 -0
  83. package/skills/slide-types/SKILL.md +384 -0
  84. package/skills/slidenerds-runtime/SKILL.md +163 -0
  85. package/skills/speaker-notes/SKILL.md +128 -0
  86. package/skills/strategic-frameworks/SKILL.md +392 -0
  87. package/skills/visual-design/SKILL.md +373 -0
  88. package/templates/analytics/custom.tsx.tmpl +20 -0
  89. package/templates/analytics/ga4.tsx.tmpl +15 -0
  90. package/templates/analytics/gtm.tsx.tmpl +9 -0
  91. package/templates/analytics/plausible.tsx.tmpl +10 -0
  92. package/templates/analytics/posthog.tsx.tmpl +14 -0
  93. package/templates/next-app/CLAUDE.md.tmpl +574 -0
  94. package/templates/next-app/README.md.tmpl +35 -0
  95. package/templates/next-app/app/globals.css.tmpl +274 -0
  96. package/templates/next-app/app/layout.tsx.tmpl +31 -0
  97. package/templates/next-app/app/page.tsx.tmpl +38 -0
  98. package/templates/next-app/brand.config.ts.tmpl +32 -0
  99. package/templates/next-app/package.json.tmpl +25 -0
  100. package/templates/next-app/postcss.config.mjs.tmpl +8 -0
  101. package/templates/next-app/tsconfig.json.tmpl +21 -0
@@ -0,0 +1,373 @@
1
+ ---
2
+ name: visual-design
3
+ description: Layout, spacing, typography scale, and compositional rules for polished slidenerds slides
4
+ ---
5
+
6
+ # Visual design skill
7
+
8
+ Use this skill whenever building or reviewing slide content. These rules govern layout, spacing, composition, and visual hierarchy. They are independent of color palette and font choice -- users bring their own brand tokens. This skill governs how those tokens are applied spatially.
9
+
10
+ ## Canvas and safe zones
11
+
12
+ The canvas is 16:9 (1920x1080 logical pixels). All content must respect two boundaries:
13
+
14
+ - **Action safe**: 3.5% inset from each edge. No content outside this boundary.
15
+ - **Title safe**: 5% inset from each edge. All readable text must stay inside this boundary.
16
+
17
+ For slidenerds, `--slide-padding` controls the outer margin. Set it to 5-8% of the smaller dimension. On a 1080-tall canvas, that is 54-86px, which maps to `3.5rem` to `5.5rem`. The default is `5rem`.
18
+
19
+ ```
20
+ +-------------------------------------------+
21
+ | 3.5% action safe |
22
+ | +-------------------------------------+ |
23
+ | | 5% title safe | |
24
+ | | | |
25
+ | | Content lives here | |
26
+ | | | |
27
+ | +-------------------------------------+ |
28
+ +-------------------------------------------+
29
+ ```
30
+
31
+ ## The default layout is top-left anchored
32
+
33
+ This is the most important layout rule. The majority of slides in any professional deck anchor content to the top-left corner, with the title at a fixed position and content flowing downward. The bottom portion of the slide is breathing room.
34
+
35
+ **Do NOT vertically center content on most slides.** Vertically centered content is only appropriate for these specific slide types:
36
+
37
+ - **Big stat**: A single number that dominates the slide
38
+ - **Section divider**: A section name between major parts of the deck
39
+ - **Quote**: A blockquote with attribution
40
+ - **Closing**: Contact info or "Questions?"
41
+
42
+ Every other slide type -- charts, tables, text, timelines, dashboards, diagrams, team slides, process flows, comparisons, icon grids -- uses top-left anchored layout. The title starts near the top of the slide at a consistent Y position across all content slides. This consistency is what makes a deck feel like a designed system rather than a collection of individual slides.
43
+
44
+ ```
45
+ WRONG (everything centered -- looks like a default template):
46
+ +-------------------------------------------+
47
+ | |
48
+ | |
49
+ | Title |
50
+ | Content here |
51
+ | |
52
+ | |
53
+ +-------------------------------------------+
54
+
55
+ RIGHT for text/bullets/tables (anchored below title):
56
+ +-------------------------------------------+
57
+ | SECTION LABEL |
58
+ | Title |
59
+ | |
60
+ | - Bullet point one |
61
+ | - Bullet point two |
62
+ | - Bullet point three |
63
+ | |
64
+ | [breathing room] |
65
+ +-------------------------------------------+
66
+
67
+ RIGHT for diagrams/charts/shapes (title top-left, visual centered):
68
+ +-------------------------------------------+
69
+ | SECTION LABEL |
70
+ | Title |
71
+ | |
72
+ | [diagram or chart centered |
73
+ | in the remaining space] |
74
+ | |
75
+ +-------------------------------------------+
76
+ ```
77
+
78
+ There are two sub-patterns for top-left anchored slides:
79
+
80
+ 1. **Text content** (bullets, numbered lists, tables, KPI grids): Content flows directly below the title, anchored to the left. The bottom is breathing room.
81
+ 2. **Visual content** (diagrams, charts, shapes, process flows, icon grids, team avatars): Title stays top-left. The visual centers both horizontally and vertically in the remaining space below the title. Use `flex-1 flex items-center justify-center` on the visual container.
82
+
83
+ ## The one-thing rule
84
+
85
+ Each slide communicates exactly one idea. One stat. One chart. One comparison. One quote. The moment a slide tries to say two things, it stops feeling designed and starts feeling assembled.
86
+
87
+ Ask: "What is the single sentence this slide says?" If you need two sentences, make two slides.
88
+
89
+ ## Content density limits
90
+
91
+ | Deck style | Max words per slide | Max content chunks | Whitespace ratio |
92
+ |---|---|---|---|
93
+ | Keynote (Apple, Stripe) | 10-30 | 2 | 60-70% |
94
+ | Board / pitch (Sequoia) | 30-50 | 3-4 | 45-55% |
95
+ | Training / educational | 40-75 | 4 | 35-45% |
96
+
97
+ A "content chunk" is a visually distinct group: a text block, a chart, a stat with its label, an image with caption.
98
+
99
+ Never exceed 3 distinct type sizes on one slide: title, body, and detail. A fourth size signals too much content.
100
+
101
+ ## Typography scale
102
+
103
+ Use a modular scale ratio to define type sizes. The two ratios that work for presentations:
104
+
105
+ - **Perfect fourth (1.333)**: body 24 > 32 > 42 > 56. Good for content-heavy slides.
106
+ - **Perfect fifth (1.5)**: body 24 > 36 > 54 > 80. Good for keynote moments.
107
+
108
+ Pick one ratio per deck and use it everywhere.
109
+
110
+ ### Size floors for projection
111
+
112
+ | Role | Minimum | Recommended |
113
+ |---|---|---|
114
+ | Title / hero | 36pt | 56-80pt |
115
+ | Heading (H2) | 28pt | 36-48pt |
116
+ | Body text | 20pt | 24-32pt |
117
+ | Caption / label | 16pt | 18-20pt |
118
+
119
+ Never set text smaller than 16pt. At projection distance, anything below that disappears.
120
+
121
+ ### Line height
122
+
123
+ - Titles: `leading-none` to `leading-tight` (1.0-1.15). Tight title spacing is a core differentiator between polished and amateur decks.
124
+ - Body: `leading-relaxed` (1.35-1.5). Open enough for distance reading.
125
+ - Labels and captions: `leading-snug` (1.2-1.3).
126
+
127
+ ### Letter spacing
128
+
129
+ Tight negative tracking on headings creates a confident, editorial feel:
130
+
131
+ - Titles: `tracking-tight` (-0.02em)
132
+ - Body: `tracking-normal` (0)
133
+ - Uppercase labels: `tracking-widest` (0.1-0.2em)
134
+
135
+ ## Grid system
136
+
137
+ Use a 12-column conceptual grid for horizontal layout. Twelve divides into halves (6+6), thirds (4+4+4), quarters (3+3+3+3), and asymmetric splits.
138
+
139
+ ### Column allocations by slide type
140
+
141
+ | Slide type | Layout | Tailwind |
142
+ |---|---|---|
143
+ | Title, big stat, quote | Content centered or left in 8-10 cols | `max-w-4xl mx-auto` or left-aligned |
144
+ | Two-up (text + image) | 5 cols text, 7 cols image (asymmetric) | `grid grid-cols-12`, `col-span-5` / `col-span-7` |
145
+ | Three stats | 4 cols each | `grid grid-cols-3 gap-16` |
146
+ | Chart + annotation | Full width chart, annotation below | Single column, stacked |
147
+ | Table | 10 cols centered | `max-w-4xl mx-auto` |
148
+
149
+ Asymmetric splits (5:7, 4:8) look more designed than symmetric ones (6:6). Use them by default for two-element layouts.
150
+
151
+ ## Spacing system
152
+
153
+ ### The hierarchy rule
154
+
155
+ Internal spacing (within a group) must always be smaller than external spacing (between groups). The ratio is 1:2.
156
+
157
+ ```
158
+ Title
159
+ [0.5x heading height gap]
160
+ Body text paragraph
161
+ [1x body line height gap]
162
+ Body text paragraph
163
+
164
+ [2-3x body line height gap] <-- section break
165
+
166
+ Next group title
167
+ ```
168
+
169
+ ### Specific spacing values
170
+
171
+ | Relationship | Spacing | Tailwind |
172
+ |---|---|---|
173
+ | Heading to body | 0.5-1x heading line height | `mt-3` to `mt-6` |
174
+ | Between body paragraphs | 0.75-1x body line height | `mt-4` |
175
+ | Between content chunks | 2-3x body line height | `mt-10` to `mt-16` |
176
+ | Between section label and heading | `mt-3` | Small, tight coupling |
177
+ | Chart/image to its caption | `mt-4` to `mt-6` | Visually grouped |
178
+ | Stat number to its label | `mt-2` to `mt-3` | Tight, single unit |
179
+
180
+ ### The double-spacing heuristic
181
+
182
+ Whatever spacing looks right at your desk, double it. Slides are viewed from distance. Spacing that feels generous while editing feels normal on a projector. Spacing that feels normal while editing feels cramped projected.
183
+
184
+ ## Visual hierarchy through opacity
185
+
186
+ Opacity is more effective than color changes for creating hierarchy on slides. It works with any palette.
187
+
188
+ | Level | Opacity | Use |
189
+ |---|---|---|
190
+ | Primary | 100% | Title, hero stat, key data |
191
+ | Secondary | 60-70% | Body text, labels |
192
+ | Tertiary | 40-50% | Captions, attribution, metadata |
193
+ | Decorative | 10-25% | Background elements, dividers |
194
+
195
+ Apply with Tailwind: `opacity-100`, `opacity-60`, `opacity-40`.
196
+
197
+ For text on dark backgrounds, consider `99%` opacity on primary text (not 100%). This is subtle but softens the rendering and reduces harshness.
198
+
199
+ ## Compositional patterns
200
+
201
+ ### Rule of thirds
202
+
203
+ Divide the slide into a 3x3 grid. Place focal elements at the four intersection points. In a 1920x1080 frame, the power points are at approximately (640, 360), (1280, 360), (640, 720), (1280, 720).
204
+
205
+ Do not center every slide. Reserve centered composition for hero moments (big stat, title, closing). Use rule-of-thirds positioning for content slides.
206
+
207
+ ### Asymmetry over symmetry
208
+
209
+ Perfectly centered, symmetric layouts read as "default template." Use asymmetry to create visual tension:
210
+
211
+ - Left-aligned text on a centered slide
212
+ - Content weighted to one side with whitespace on the other
213
+ - Uneven column splits (5:7, 4:8)
214
+
215
+ ### Consistent anchor points across slides
216
+
217
+ The single biggest signal of a "designed" deck vs. an "assembled" one: recurring elements occupy the same position on every slide.
218
+
219
+ - Section labels: same x and y on every slide that has one
220
+ - Titles: same y-position (baseline alignment) across all content slides
221
+ - Body text: same x-position (left edge) across all content slides
222
+ - Logo / page indicator: same corner, same size, every slide
223
+
224
+ Define these positions once and reuse them. In slidenerds, this means extracting consistent padding and positioning values.
225
+
226
+ ### The left-content, right-atmosphere pattern
227
+
228
+ Used in Apple keynotes and the Supabase re:Invent deck: content occupies the left 50-55% of the slide. The right side is reserved for atmospheric imagery, gradient wash, or intentional emptiness. This creates a strong reading anchor on the left and visual breathing room on the right.
229
+
230
+ ## Section structure
231
+
232
+ ### Section labels
233
+
234
+ Every content slide (except title and closing) should have a section label -- a small uppercase text above the title that tells the audience where they are in the deck.
235
+
236
+ ```tsx
237
+ <p className="text-sm font-semibold tracking-[0.2em] uppercase mb-3"
238
+ style={{ color: 'var(--color-accent)' }}>
239
+ Revenue
240
+ </p>
241
+ <h2 className="text-4xl font-bold tracking-tight">
242
+ ARR trajectory
243
+ </h2>
244
+ ```
245
+
246
+ The label uses the accent color, uppercase, wide tracking. The title uses the primary text color, tight tracking. The contrast between the two (small+wide vs. large+tight) creates clear hierarchy.
247
+
248
+ ### Section dividers
249
+
250
+ Between major sections, insert a divider slide. It contains only a section number and title, centered. Use the primary/surface background color, not the standard slide background, to create a visual break.
251
+
252
+ ## Slide type spacing recipes
253
+
254
+ ### Title slide
255
+
256
+ ```
257
+ Bottom-aligned layout:
258
+ accent-line (48x3px) at bottom 35%
259
+ title (56-72pt, tight) mt-8 below line
260
+ subtitle (20-24pt, 50% opacity) mt-5
261
+ metadata row (12-14pt, 40% opacity, uppercase tracking) mt-16
262
+ ```
263
+
264
+ Content gravity is bottom-left. The top 50-60% of the slide is breathing room.
265
+
266
+ ### Big stat slide
267
+
268
+ ```
269
+ Center-aligned layout:
270
+ stat number (80-160pt, accent color, glow) centered
271
+ label (24-32pt, 60% opacity) mt-2 to mt-4
272
+ context badge (pill shape, accent-dim bg) mt-8 to mt-10
273
+ ```
274
+
275
+ The stat is optically centered (slightly above true center). The label sits close to the number (they are a single unit). The context badge has more separation.
276
+
277
+ ### Chart slide
278
+
279
+ ```
280
+ Left-aligned layout:
281
+ section label + title top section
282
+ chart in card surface mt-8 to mt-12, full width up to max-w-4xl
283
+ annotation with bullet dot mt-5 to mt-6 below chart
284
+ ```
285
+
286
+ Charts sit inside a card surface (subtle border, slightly elevated background) to separate them from the slide background. One chart per slide. The annotation is a single sentence with a small accent-colored dot before it.
287
+
288
+ Charts must use the full available width of the slide -- never constrain them to a narrow `max-width`. Use `flex-1` with `minHeight: 0` so the chart grows to fill available vertical space within the slide padding. The `ResponsiveContainer` should use `height="100%"` not a fixed pixel height.
289
+
290
+ ### Comparison table
291
+
292
+ ```
293
+ Left-aligned layout:
294
+ section label + title top section
295
+ table in card surface mt-8, full width up to max-w-4xl
296
+ header row: uppercase, small, muted, elevated bg
297
+ data rows: revealed one at a time via data-step
298
+ ```
299
+
300
+ Table headers use the same style as section labels (small, uppercase, wide tracking, muted color). Data cells use body text size. Accent color highlights the "winning" values.
301
+
302
+ ### Quote slide
303
+
304
+ ```
305
+ Center-aligned layout:
306
+ large open-quote glyph (accent color, 30% opacity) decorative
307
+ quote text (28-36pt, light weight, relaxed leading) mt-6 to mt-8
308
+ avatar circle + name + role (left-aligned pair) mt-10 to mt-12
309
+ ```
310
+
311
+ Constrain the quote to `max-w-3xl` for comfortable line length. The open-quote glyph is decorative, not structural.
312
+
313
+ ### Timeline / roadmap
314
+
315
+ ```
316
+ Top-left title + centered visual layout:
317
+ section label + title top-left anchored
318
+ visual container flex-1 flex items-center justify-center
319
+ horizontal connector line thin, muted, full width within container
320
+ timeline nodes grid cols, each with:
321
+ dot (accent, with glow)
322
+ quarter label (bold, mt-4)
323
+ milestone name (medium, mt-1)
324
+ detail (small, muted, mt-1)
325
+ ```
326
+
327
+ The title stays top-left. The timeline itself centers vertically and horizontally in the remaining space below the title. Completed milestones use full accent color. Future milestones use dimmed dot (muted background, no glow).
328
+
329
+ ## Background treatments
330
+
331
+ ### Gradient mesh
332
+
333
+ Subtle radial gradients in the background create depth without competing with content. Use the accent color at 4-8% opacity in two overlapping ellipses at different positions.
334
+
335
+ ```css
336
+ background:
337
+ radial-gradient(ellipse at 20% 50%, rgba(accent, 0.08) 0%, transparent 50%),
338
+ radial-gradient(ellipse at 80% 20%, rgba(accent, 0.04) 0%, transparent 40%),
339
+ var(--color-background);
340
+ ```
341
+
342
+ Alternate between warm and cool mesh positions across slides for visual variety.
343
+
344
+ ### Film grain
345
+
346
+ A subtle noise texture at 2-3% opacity adds tactile quality to dark backgrounds. Apply as a pseudo-element on `[data-slide]` so it covers every slide automatically.
347
+
348
+ ### Section divider backgrounds
349
+
350
+ Use a linear gradient from primary to surface color. This is the visual cue that says "this is a structural break, not a content slide."
351
+
352
+ ## Card surfaces
353
+
354
+ Charts, tables, and code blocks sit inside card surfaces rather than directly on the slide background. A card surface is:
355
+
356
+ - Background: `var(--color-surface)` (one step lighter than slide background)
357
+ - Border: 1px solid at 6% white opacity
358
+ - Border radius: 12px
359
+ - Padding: 1.5-2rem
360
+
361
+ Cards create depth and separation. They are the visual equivalent of a frame around a painting.
362
+
363
+ ## What to avoid
364
+
365
+ - Centering everything. Most slides are top-left anchored. Only big stat, section divider, quote, and closing use centered layout. If you are unsure, use top-left.
366
+ - More than one chart per slide.
367
+ - Text below 16pt.
368
+ - More than 3 type sizes on one slide.
369
+ - Symmetric column splits when asymmetric would work.
370
+ - Content that fills the entire slide with no whitespace.
371
+ - Background images behind text without a contrast overlay.
372
+ - Decorative elements that do not support the content hierarchy.
373
+ - Inconsistent positioning of recurring elements across slides.
@@ -0,0 +1,20 @@
1
+ import Script from 'next/script'
2
+
3
+ /**
4
+ * Custom analytics component.
5
+ *
6
+ * Wire your analytics provider here. This component is loaded in the root
7
+ * layout after the page is interactive.
8
+ *
9
+ * Common patterns:
10
+ * - Add a Script tag with your provider's snippet
11
+ * - Import and initialize your provider's SDK
12
+ * - Track page views and slide navigation events
13
+ */
14
+ export const CustomAnalytics = () => (
15
+ <Script
16
+ id="custom-analytics"
17
+ strategy="afterInteractive"
18
+ src="/analytics/custom.js"
19
+ />
20
+ )
@@ -0,0 +1,15 @@
1
+ import Script from 'next/script'
2
+
3
+ export const GA4Analytics = () => (
4
+ <>
5
+ <Script
6
+ src={`https://www.googletagmanager.com/gtag/js?id={{ANALYTICS_ID}}`}
7
+ strategy="afterInteractive"
8
+ />
9
+ <Script
10
+ id="ga4-init"
11
+ strategy="afterInteractive"
12
+ src={`/analytics/ga4-init.js`}
13
+ />
14
+ </>
15
+ )
@@ -0,0 +1,9 @@
1
+ import Script from 'next/script'
2
+
3
+ export const GTMAnalytics = () => (
4
+ <Script
5
+ id="gtm-script"
6
+ strategy="afterInteractive"
7
+ src={`https://www.googletagmanager.com/gtm.js?id={{ANALYTICS_ID}}`}
8
+ />
9
+ )
@@ -0,0 +1,10 @@
1
+ import Script from 'next/script'
2
+
3
+ export const PlausibleAnalytics = () => (
4
+ <Script
5
+ defer
6
+ data-domain="{{ANALYTICS_ID}}"
7
+ src="https://plausible.io/js/script.js"
8
+ strategy="afterInteractive"
9
+ />
10
+ )
@@ -0,0 +1,14 @@
1
+ import Script from 'next/script'
2
+
3
+ export const PostHogAnalytics = () => (
4
+ <Script
5
+ id="posthog-script"
6
+ strategy="afterInteractive"
7
+ src="https://app.posthog.com/static/array.js"
8
+ onLoad={() => {
9
+ if (typeof window !== 'undefined' && (window as Record<string, unknown>).posthog) {
10
+ (window as Record<string, unknown> & { posthog: { init: (key: string, opts: Record<string, string>) => void } }).posthog.init('{{ANALYTICS_ID}}', { api_host: 'https://app.posthog.com' })
11
+ }
12
+ }}
13
+ />
14
+ )