@proveanything/smartlinks 1.7.0 → 1.7.2

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.
@@ -0,0 +1,372 @@
1
+ # SmartLinks Microapp Development Guide
2
+
3
+ > **Platform revision:** R4.6 · **SDK minimum:** `@proveanything/smartlinks@1.4.1`
4
+ > **Last updated:** 2026-03-03
5
+
6
+ ---
7
+
8
+ ## What Is a SmartLinks Microapp?
9
+
10
+ SmartLinks microapps are **modular, embeddable React applications** that extend the SmartLinks digital twin platform. They provide specialised functionality — product information displays, warranty registration, competitions, pamphlet generators, and more — while inheriting context, authentication, and theming from the parent platform.
11
+
12
+ ### The Digital Twin Ecosystem
13
+
14
+ SmartLinks is a **digital twin platform** that connects physical products to digital experiences. Each physical item (a wine bottle, a luxury handbag, a piece of equipment) has a corresponding digital identity — a "proof" — that can be scanned, claimed, and enriched with data over time.
15
+
16
+ Microapps are the **extensibility layer** of this ecosystem. Rather than building monolithic features into the core platform, functionality is distributed across purpose-built apps that:
17
+
18
+ - **Embed seamlessly** via iframes in the SmartLinks Portal (public) and Admin Console (management)
19
+ - **Share context** through URL parameters (collection, product, or proof being viewed)
20
+ - **Inherit identity** from the parent platform's authentication system
21
+ - **Adapt visually** to the brand's theme configuration
22
+ - **Communicate bidirectionally** with the parent via postMessage for deep linking and navigation
23
+
24
+ ### Deployment Modes
25
+
26
+ Each microapp can be consumed in up to four ways:
27
+
28
+ | Mode | Embedding | Use Case |
29
+ |------|-----------|---------|
30
+ | **Iframe App** | Full React app in iframe | Complete experiences with routing, forms, complex UI |
31
+ | **Widget** | React component in parent context | Lightweight previews, cards, summaries (~10 KB, loaded immediately) |
32
+ | **Container** | Full app in parent React context | Complete experience without iframe (~150 KB+, lazy-loaded) |
33
+ | **Executor** | JS library (no UI) | Programmatic config, SEO metadata, LLM content for AI/server |
34
+
35
+ Widgets and containers both run in the parent's React tree (not iframes). Executors have no UI — they expose functions that AI orchestrators and the server call directly.
36
+
37
+ ---
38
+
39
+ ## SDK Documentation Reference
40
+
41
+ The SmartLinks SDK (`@proveanything/smartlinks`) includes comprehensive documentation in `node_modules/@proveanything/smartlinks/docs/`. **Always read these files for detailed implementation guidance.**
42
+
43
+ > **Minimum SDK version: `1.4.1`** — Ensure `@proveanything/smartlinks` is at least this version. If not, update with `npm install @proveanything/smartlinks@latest`.
44
+
45
+ | Topic | File | When to Use |
46
+ |-------|------|-------------|
47
+ | **API Reference** | `docs/API_SUMMARY.md` | Complete SDK function reference, types, error handling |
48
+ | **Multi-Page Architecture** | `docs/mpa.md` | Build pipeline, entry points, multi-page setup, content hashing |
49
+ | **AI & Chat** | `docs/ai.md` | Chat completions, RAG, streaming, tool calling, voice, podcasts, TTS |
50
+ | **Theming** | `docs/theme.system.md` | Implementing dynamic themes via URL params or postMessage |
51
+ | **Theme Defaults** | `docs/theme-defaults.md` | Default colour values for light/dark modes |
52
+ | **Internationalization** | `docs/i18n.md` | Adding multi-language support, translation patterns |
53
+ | **Widgets** | `docs/widgets.md` | Building widgets, shared deps contract, settings schema |
54
+ | **Containers** | `docs/containers.md` | Building full-app embeddable containers (lazy-loaded) |
55
+ | **Executors** | `docs/executor.md` | Building executor bundles for SEO, LLM content, programmatic config |
56
+ | **Deep Linking** | `docs/deep-link-discovery.md` | URL state management, navigable states, portal menus, AI nav |
57
+ | **Interactions** | `docs/interactions.md` | Event tracking, analytics, voting, competitions, journey triggers |
58
+ | **AI-Native Manifests** | `docs/manifests.md` | `app.manifest.json`, `app.admin.json`, `ai-guide.md` structure |
59
+ | **App Config Files** | `docs/app-manifest.md` | Full field-by-field reference for both JSON config files |
60
+ | **Real-time Messaging** | `docs/realtime.md` | Adding Ably real-time features (chat, live updates) |
61
+ | **Liquid Templates** | `docs/liquid-templates.md` | Dynamic content rendering with LiquidJS |
62
+ | **Iframe Responder** | `docs/iframe-responder.md` | Iframe communication and proxy mode internals |
63
+ | **AI Guide Template** | `docs/ai-guide-template.md` | Template for creating `public/ai-guide.md` — customise per app |
64
+
65
+ ---
66
+
67
+ ## Technical Overview
68
+
69
+ - **Iframe-based** — Apps run inside iframes in both the public Portal and Admin Console
70
+ - **Hash routing** — Uses `/#/` routes for iframe compatibility (e.g., `/#/`, `/#/admin`)
71
+ - **Context via URL params** — All contextual data is passed through URL parameters
72
+ - **SmartLinks NPM module** — All data access and platform interaction goes through `@proveanything/smartlinks`
73
+ - **No standalone auth** — Authentication is handled by the parent SmartLinks platform
74
+ - **Multi-page build** — Separate bundles for public and admin — see `docs/mpa.md`
75
+
76
+ ---
77
+
78
+ ## Data Model Hierarchy
79
+
80
+ ```
81
+ Collection (Business/Brand)
82
+ └── Product (Product Type/Definition)
83
+ └── Proof (Specific Instance with Owner)
84
+ └── Attestation (User/Admin Data on Proof)
85
+ ```
86
+
87
+ | Entity | Description | Example |
88
+ |--------|-------------|---------|
89
+ | **Collection** | Top-level container representing a business or brand | "Acme Wine Co." |
90
+ | **Product** | A type of product (not a specific item) | "2023 Cabernet Sauvignon" |
91
+ | **Proof** | A specific instance of a product, often with an owner | Bottle #12345 claimed by user@email.com |
92
+ | **Attestation** | Data attached to a proof by users or admins | Warranty registration, tasting notes |
93
+
94
+ ### URL Parameters
95
+
96
+ | Parameter | Type | Description |
97
+ |-----------|------|-------------|
98
+ | `collectionId` | string | The collection being viewed/managed |
99
+ | `productId` | string | The specific product (within collection) |
100
+ | `proofId` | string | The specific proof instance |
101
+ | `appId` | string | This app's unique identifier (for data scoping) |
102
+ | `dark` | `1` or `0` | Whether to use dark mode |
103
+ | `theme` | base64 | Full theme configuration (see `docs/theme.system.md`) |
104
+
105
+ ---
106
+
107
+ ## Authentication & Permissions
108
+
109
+ SmartLinks apps do **not** implement their own authentication. The parent platform handles all auth:
110
+
111
+ - Use `SL.auth.getAccount()` to check if a user is logged in
112
+ - The response includes whether the user is an `admin` or regular user
113
+ - Many SmartLinks API functions behave differently based on admin status
114
+
115
+ | Capability | Admin | Regular User |
116
+ |------------|-------|-------------|
117
+ | Read collection/product data | ✅ | ✅ |
118
+ | Write app configuration | ✅ | ❌ |
119
+ | Write attestations | ✅ | ✅ (own proofs only) |
120
+ | Access admin-only API fields | ✅ | ❌ |
121
+
122
+ ---
123
+
124
+ ## Data Storage Patterns
125
+
126
+ ### ⚠️ Critical: Admin Mode Flag
127
+
128
+ **When building admin interfaces, you MUST pass `admin: true` in API options.**
129
+
130
+ Without this flag, API calls use the public endpoint and will fail to write data:
131
+
132
+ ```typescript
133
+ // ❌ WRONG — will fail in admin interface
134
+ await SL.appConfiguration.setConfig({ collectionId, appId, config: myConfig });
135
+
136
+ // ✅ CORRECT — include admin: true
137
+ await SL.appConfiguration.setConfig({ collectionId, appId, config: myConfig, admin: true });
138
+ ```
139
+
140
+ This applies to all write operations: `setConfig`, `setDataItem`, `updateDataItem`, etc.
141
+
142
+ ### Config vs Data
143
+
144
+ | Storage Type | Function | Use Case |
145
+ |-------------|---------|---------|
146
+ | **Config** (`getConfig`/`setConfig`) | Single JSON document | App settings, feature flags, global options |
147
+ | **Data** (`getData`/`setDataItem`) | Array of documents with IDs | Lists of items, records, entries |
148
+
149
+ Both can be scoped to **collection level** or **product level** by including `productId`.
150
+
151
+ ### Attestations (Proof-level data)
152
+
153
+ For data attached to specific proof instances, use `SL.attestation.create()` and `SL.attestation.list()`.
154
+
155
+ ---
156
+
157
+ ## Error Handling
158
+
159
+ The SmartLinks SDK returns structured `SmartlinksApiError` objects. Use `instanceof SmartlinksApiError` to access `.statusCode`, `.message`, and helper methods:
160
+
161
+ - `.isAuthError()` — 401/403 responses
162
+ - `.isNotFound()` — 404 responses
163
+ - `.isRateLimited()` — 429 responses
164
+ - `.isServerError()` — 5xx responses
165
+
166
+ See `docs/API_SUMMARY.md` for complete error handling documentation.
167
+
168
+ ---
169
+
170
+ ## AI Integration
171
+
172
+ SmartLinks provides comprehensive AI capabilities through the `SL.ai` namespace. **Always use SmartLinks AI for microapps** — do not integrate external AI services (OpenAI, Anthropic, Lovable Cloud AI, etc.) directly.
173
+
174
+ Key capabilities: chat completions (streaming + tool calling), RAG document Q&A, voice input/output, podcast generation, text-to-speech, model listing.
175
+
176
+ See `docs/ai.md` for complete documentation.
177
+
178
+ ---
179
+
180
+ ## Interactions & Event Tracking
181
+
182
+ The `SL.interactions` namespace tracks user engagement — competition entries, votes, form submissions, warranty registrations. Events can trigger automated journeys and communications.
183
+
184
+ Key functions: `submitPublicEvent()`, `appendEvent()` (admin), `countsByOutcome()`, `query()`.
185
+
186
+ See `docs/interactions.md` for complete documentation.
187
+
188
+ ---
189
+
190
+ ## Liquid Templating
191
+
192
+ Use the `<LiquidContent>` component, `useLiquidTemplate` hook, and `renderLiquid` utility for admin-configured dynamic content using Liquid syntax.
193
+
194
+ See `docs/liquid-templates.md` for full context variables, filters, and examples.
195
+
196
+ ---
197
+
198
+ ## Design Principles
199
+
200
+ ### Public Interface (Portal)
201
+
202
+ - **Mobile-first** — Assume users are on phones
203
+ - **Non-technical** — Never show raw IDs or technical data
204
+ - **Accessible** — Follow WCAG guidelines
205
+
206
+ ### Admin Interface
207
+
208
+ - **Feature-rich** — Power users expect advanced controls
209
+ - **Efficient** — Minimise clicks for common tasks
210
+ - **Desktop-optimised** — Admins typically use desktop browsers
211
+
212
+ ### Theming
213
+
214
+ Apps receive theme configuration from the parent platform via URL parameter (`?theme=base64…`) and PostMessage updates. See `docs/theme.system.md`.
215
+
216
+ ---
217
+
218
+ ## Common Hooks
219
+
220
+ ```typescript
221
+ // Fetch collection/product/proof data
222
+ useCollectionData(collectionId)
223
+ useProductData(collectionId, productId)
224
+ useProofData(collectionId, productId, proofId)
225
+
226
+ // Fetch app configuration
227
+ useCollectionAppConfig(collectionId, appId)
228
+ useProductAppConfig(collectionId, productId, appId)
229
+
230
+ // Fetch app data (array of items)
231
+ useCollectionAppData(collectionId, appId)
232
+ useProductAppData(collectionId, productId, appId)
233
+
234
+ // Fetch attestations
235
+ useAttestationsData(collectionId, productId, proofId)
236
+
237
+ // URL parameter management
238
+ usePersistentQueryParams()
239
+
240
+ // Theme management
241
+ useSmartLinksTheme()
242
+
243
+ // Liquid templating
244
+ useLiquidTemplate(templateString, contextData)
245
+ ```
246
+
247
+ ---
248
+
249
+ ## API Namespaces
250
+
251
+ The SmartLinks SDK is organised into namespaces. See `docs/API_SUMMARY.md` for the complete reference. Key namespaces:
252
+
253
+ - `appConfiguration` — Config and data storage (most apps use this)
254
+ - `attestation` — Proof-level user/admin data
255
+ - `interactions` — Event tracking and analytics
256
+ - `ai` — AI content generation, chat, RAG (see `docs/ai.md`)
257
+ - `auth` / `authKit` — Admin and end-user authentication
258
+ - `contact` — Customer contact management
259
+ - `comms` / `broadcasts` — Notifications and campaigns
260
+ - `asset` — File/image uploads
261
+ - `realtime` — Ably real-time messaging (see `docs/realtime.md`)
262
+
263
+ ---
264
+
265
+ ## File Structure
266
+
267
+ ```
268
+ ├── index.html ← Public portal entry
269
+ ├── admin.html ← Admin console entry
270
+ ├── public/
271
+ │ ├── app.manifest.json ← Public discovery manifest
272
+ │ ├── app.admin.json ← Admin manifest (on-demand)
273
+ │ └── ai-guide.md ← AI orchestrator prose guide
274
+ ├── src/
275
+ │ ├── main.tsx ← Public React entry
276
+ │ ├── admin-main.tsx ← Admin React entry
277
+ │ ├── App.tsx ← Shared providers (QueryClient, Toaster, etc.)
278
+ │ ├── PublicApp.tsx ← Public app shell (routes only public pages)
279
+ │ ├── AdminApp.tsx ← Admin app shell (routes only admin pages)
280
+ │ ├── components/ ← Reusable UI components
281
+ │ ├── containers/ ← Embeddable full-app containers
282
+ │ ├── executor/ ← Executor bundle (SEO, LLM content, config API)
283
+ │ ├── hooks/ ← React hooks (data fetching, state)
284
+ │ ├── pages/
285
+ │ │ ├── PublicPage.tsx ← Portal content (/#/)
286
+ │ │ ├── AdminPage.tsx ← Admin content (admin.html#/)
287
+ │ │ └── DevPage.tsx ← Development helper (dev only)
288
+ │ ├── widgets/ ← Embeddable widget components
289
+ │ └── utils/
290
+ │ ├── smartlinks/ ← SmartLinks utilities
291
+ │ └── theme.ts ← Theme utilities
292
+ ├── vite.config.ts ← Multi-page build config
293
+ ├── vite.config.widget.ts ← Widget library build config
294
+ ├── vite.config.container.ts ← Container library build config
295
+ └── vite.config.executor.ts ← Executor library build config
296
+ ```
297
+
298
+ ---
299
+
300
+ ## Anti-Patterns to Avoid
301
+
302
+ ❌ **Don't implement custom auth** — Use SmartLinks auth via `SL.auth.getAccount()`
303
+
304
+ ❌ **Don't use BrowserRouter** — Always use HashRouter for iframe compatibility
305
+
306
+ ❌ **Don't hardcode URLs** — Use relative paths and let the platform provide context
307
+
308
+ ❌ **Don't store secrets in code** — Use environment variables or platform configuration
309
+
310
+ ❌ **Don't assume screen size** — Support both mobile (Portal) and desktop (Admin)
311
+
312
+ ❌ **Don't expose technical IDs** — Show human-readable names to users
313
+
314
+ ❌ **Don't import AdminPage in PublicApp** — Keep bundles separate for optimal size
315
+
316
+ ❌ **Don't use external AI services** — Use SmartLinks AI via `SL.ai`, not OpenAI/Anthropic/Lovable Cloud AI directly
317
+
318
+ ❌ **Don't forget `admin: true`** — All admin write operations require this flag
319
+
320
+ ---
321
+
322
+ ## Quick Reference
323
+
324
+ ### Initialise the API
325
+
326
+ ```typescript
327
+ import { initializeAPI } from '@/utils/smartlinks/initialization';
328
+ initializeAPI(); // Call once at app startup
329
+ ```
330
+
331
+ ### Get Context from URL
332
+
333
+ ```typescript
334
+ const { persistentQueryParams } = usePersistentQueryParams();
335
+ const { collectionId, productId, appId } = persistentQueryParams;
336
+ ```
337
+
338
+ ### Check Admin Status
339
+
340
+ ```typescript
341
+ const account = await SL.auth.getAccount();
342
+ const isAdmin = account?.admin === true;
343
+ ```
344
+
345
+ ### Save Configuration (Admin Only)
346
+
347
+ ```typescript
348
+ await SL.appConfiguration.setConfig({
349
+ collectionId, appId,
350
+ config: { myKey: 'myValue' },
351
+ admin: true // Required!
352
+ });
353
+ ```
354
+
355
+ ### Handle Dark Mode + Theming
356
+
357
+ ```typescript
358
+ // In App.tsx — already integrated in the template
359
+ useDarkMode(); // Handles ?dark=1 parameter
360
+ useSmartLinksTheme(); // Handles ?theme=base64 parameter
361
+ useDeepLinkSync(); // Syncs route changes to parent
362
+ ```
363
+
364
+ ### Deep Linking
365
+
366
+ ```typescript
367
+ const { navigateWithState, getAppState } = usePersistentQueryParams();
368
+ const { tab = 'general' } = getAppState();
369
+ navigateWithState('/', { tab: 'advanced' });
370
+ ```
371
+
372
+ See `docs/deep-link-discovery.md` for full implementation details.