@proveanything/smartlinks 2.0.57 → 2.0.60
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/api/integrations.d.ts +17 -2
- package/dist/api/integrations.js +20 -1
- package/dist/docs/API_SUMMARY.md +76 -11
- package/dist/docs/app-manifest.md +1 -1
- package/dist/docs/connectors.md +72 -30
- package/dist/docs/integrations.md +8 -0
- package/dist/docs/site-seo.md +69 -68
- package/dist/docs/websites.md +91 -0
- package/dist/openapi.yaml +108 -12
- package/dist/site.d.ts +32 -4
- package/dist/site.js +48 -5
- package/dist/types/appManifest.d.ts +55 -10
- package/dist/types/integrations.d.ts +31 -3
- package/docs/API_SUMMARY.md +76 -11
- package/docs/app-manifest.md +1 -1
- package/docs/connectors.md +72 -30
- package/docs/integrations.md +8 -0
- package/docs/site-seo.md +69 -68
- package/docs/websites.md +91 -0
- package/openapi.yaml +108 -12
- package/package.json +1 -1
package/docs/websites.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Websites: server-rendered on the SmartLinks site runtime
|
|
2
|
+
|
|
3
|
+
A website built on SmartLinks is an app whose public side is a **server-rendered site** at its own
|
|
4
|
+
address: an automatic `*.smartlinks.host` name, a chosen name, or the business's own domain. Every
|
|
5
|
+
page arrives as finished HTML, so search engines, AI crawlers and link previews see the real
|
|
6
|
+
content, and visitors see it before any JavaScript runs.
|
|
7
|
+
|
|
8
|
+
## How a request is served
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
visitor / crawler / agent
|
|
12
|
+
└─► SmartLinks site router (edge)
|
|
13
|
+
├─ /robots.txt, /sitemap.xml, /llms.txt made by the platform (site-seo.md)
|
|
14
|
+
├─ a file in your build (has an extension) served from the build, cached at the edge
|
|
15
|
+
└─ anything else your site's server renders it
|
|
16
|
+
• runs in an isolated worker, close to the SmartLinks API
|
|
17
|
+
• may call the SmartLinks API and the hosts you declare, nothing else
|
|
18
|
+
• request header x-sl-site says which site it is (SL.site.fromRequest)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The router also adds the canonical or noindex header, the security headers, and
|
|
22
|
+
`window.__SMARTLINKS_SITE__` to every HTML page (read in the browser with `SL.site.current()` or
|
|
23
|
+
`SL.readContext()`).
|
|
24
|
+
|
|
25
|
+
## The build
|
|
26
|
+
|
|
27
|
+
The website template (TanStack Start) produces this; you don't write it by hand.
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
dist/
|
|
31
|
+
├── index.html? / assets/… the client build (hashed files: cached for a year)
|
|
32
|
+
├── sitemap-paths.txt your pages, "<path> [Title]" per line (site-seo.md)
|
|
33
|
+
├── _server/ the server bundle: one ES module entry + its chunks
|
|
34
|
+
│ └── index.mjs exports default { fetch(request, env, ctx) } (WinterTC)
|
|
35
|
+
└── app.manifest.json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Manifest:
|
|
39
|
+
|
|
40
|
+
```jsonc
|
|
41
|
+
"site": {
|
|
42
|
+
"server": {
|
|
43
|
+
"main": "_server/index.mjs", // the server entry, inside the build
|
|
44
|
+
"compatibilityFlags": ["nodejs_compat"] // allowed: nodejs_compat, nodejs_compat_v2, nodejs_als
|
|
45
|
+
},
|
|
46
|
+
"network": ["api.example-weather.com"] // other hosts the server may call (optional)
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
On publish, the server folder becomes the site's server for that channel. Promote copies the same
|
|
51
|
+
bytes. `_server/` is never served to visitors.
|
|
52
|
+
|
|
53
|
+
## The server's rules
|
|
54
|
+
|
|
55
|
+
- **Which site:** `const site = SL.site.fromRequest(request)` gives `{ host, collectionId, appId,
|
|
56
|
+
channel, canonicalHost }`. One build serves every site it's installed on, so always take the
|
|
57
|
+
collection from here, never from a constant.
|
|
58
|
+
- **Data:** call the SmartLinks API with the SDK as you would in the browser. The server reads what
|
|
59
|
+
an anonymous visitor could read on that site, and only that collection. It holds no keys and no
|
|
60
|
+
signed-in user.
|
|
61
|
+
- **Writes** (contact forms, entries, sign-ups) go to your app's **server functions**
|
|
62
|
+
(server-functions.md), called from the browser as today. Their capabilities, secrets and limits
|
|
63
|
+
apply.
|
|
64
|
+
- **Other hosts:** only those in `site.network`. Anything else is refused (`403 Blocked`).
|
|
65
|
+
- **Limits per request:** a CPU-time budget and a cap on outgoing calls. A page that needs more is
|
|
66
|
+
doing work that belongs in a server function or a scheduled job.
|
|
67
|
+
- **No secrets** in the server bundle and no Node built-ins beyond `nodejs_compat`.
|
|
68
|
+
|
|
69
|
+
## Caching
|
|
70
|
+
|
|
71
|
+
The router keeps a rendered page at the edge when your response says it may:
|
|
72
|
+
|
|
73
|
+
| Your response | At the edge |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `Cache-Control: public, s-maxage=300` (the template's default for pages) | kept up to 5 minutes |
|
|
76
|
+
| `private`, `no-store`, `no-cache`, or a `Set-Cookie` | never kept |
|
|
77
|
+
| no `Cache-Control` | never kept |
|
|
78
|
+
|
|
79
|
+
Cached pages are keyed by the release and the collection's **content generation**: when products,
|
|
80
|
+
public app records, app settings or the collection change, the generation moves and every page of
|
|
81
|
+
the collection's sites re-renders on its next visit (within about 30 seconds). Publishing a release
|
|
82
|
+
does the same. Tracking parameters (`utm_*`, `gclid`, `fbclid`…) don't create separate entries.
|
|
83
|
+
|
|
84
|
+
Keep pages the same for every visitor. Anything personal (a signed-in owner's products, a basket)
|
|
85
|
+
renders in the browser after load.
|
|
86
|
+
|
|
87
|
+
## Locally
|
|
88
|
+
|
|
89
|
+
`npm run dev` runs the site with your dev collection (`.env`: `VITE_SL_COLLECTION_ID`), because
|
|
90
|
+
there's no router to say which site it is: `SL.site.fromRequest()` is null, so fall back to it.
|
|
91
|
+
Forge's preview runs the same server code the site runtime does.
|
package/openapi.yaml
CHANGED
|
@@ -19766,7 +19766,9 @@ components:
|
|
|
19766
19766
|
type: string
|
|
19767
19767
|
sample:
|
|
19768
19768
|
type: string
|
|
19769
|
-
|
|
19769
|
+
shape:
|
|
19770
|
+
type: string
|
|
19771
|
+
serialize:
|
|
19770
19772
|
type: string
|
|
19771
19773
|
send:
|
|
19772
19774
|
type: string
|
|
@@ -19778,6 +19780,11 @@ components:
|
|
|
19778
19780
|
$ref: "#/components/schemas/ConnectorPanel"
|
|
19779
19781
|
aiGuide:
|
|
19780
19782
|
type: string
|
|
19783
|
+
recordId:
|
|
19784
|
+
type: string
|
|
19785
|
+
limits:
|
|
19786
|
+
type: object
|
|
19787
|
+
additionalProperties: true
|
|
19781
19788
|
required:
|
|
19782
19789
|
- provider
|
|
19783
19790
|
- directions
|
|
@@ -19860,7 +19867,7 @@ components:
|
|
|
19860
19867
|
type: string
|
|
19861
19868
|
required:
|
|
19862
19869
|
- records
|
|
19863
|
-
|
|
19870
|
+
ConnectorShapeInput:
|
|
19864
19871
|
type: object
|
|
19865
19872
|
properties:
|
|
19866
19873
|
installation:
|
|
@@ -19870,15 +19877,40 @@ components:
|
|
|
19870
19877
|
items:
|
|
19871
19878
|
type: object
|
|
19872
19879
|
additionalProperties: true
|
|
19873
|
-
|
|
19880
|
+
required:
|
|
19881
|
+
- installation
|
|
19882
|
+
- records
|
|
19883
|
+
ConnectorShapeResult:
|
|
19884
|
+
type: object
|
|
19885
|
+
properties:
|
|
19886
|
+
documents:
|
|
19874
19887
|
type: array
|
|
19875
19888
|
items:
|
|
19876
|
-
|
|
19889
|
+
type: object
|
|
19890
|
+
additionalProperties: true
|
|
19891
|
+
skipped:
|
|
19892
|
+
type: array
|
|
19893
|
+
items:
|
|
19894
|
+
type: object
|
|
19895
|
+
additionalProperties: true
|
|
19896
|
+
required:
|
|
19897
|
+
- documents
|
|
19898
|
+
ConnectorSerializeInput:
|
|
19899
|
+
type: object
|
|
19900
|
+
properties:
|
|
19901
|
+
installation:
|
|
19902
|
+
$ref: "#/components/schemas/ConnectorInstallation"
|
|
19903
|
+
documents:
|
|
19904
|
+
type: array
|
|
19905
|
+
items:
|
|
19906
|
+
type: object
|
|
19907
|
+
additionalProperties: true
|
|
19908
|
+
eventType:
|
|
19909
|
+
type: string
|
|
19877
19910
|
required:
|
|
19878
19911
|
- installation
|
|
19879
|
-
-
|
|
19880
|
-
|
|
19881
|
-
ConnectorTransformResult:
|
|
19912
|
+
- documents
|
|
19913
|
+
ConnectorSerializeResult:
|
|
19882
19914
|
type: object
|
|
19883
19915
|
properties:
|
|
19884
19916
|
payloads:
|
|
@@ -19906,12 +19938,26 @@ components:
|
|
|
19906
19938
|
type: object
|
|
19907
19939
|
properties:
|
|
19908
19940
|
results:
|
|
19909
|
-
type:
|
|
19910
|
-
|
|
19911
|
-
|
|
19912
|
-
|
|
19941
|
+
type: object
|
|
19942
|
+
additionalProperties: true
|
|
19943
|
+
index:
|
|
19944
|
+
type: number
|
|
19945
|
+
ok:
|
|
19946
|
+
type: boolean
|
|
19947
|
+
status:
|
|
19948
|
+
type: number
|
|
19949
|
+
error:
|
|
19950
|
+
type: string
|
|
19951
|
+
externalId:
|
|
19952
|
+
type: string
|
|
19953
|
+
retryable:
|
|
19954
|
+
type: boolean
|
|
19955
|
+
retryAfterSeconds:
|
|
19956
|
+
type: number
|
|
19913
19957
|
required:
|
|
19914
19958
|
- results
|
|
19959
|
+
- index
|
|
19960
|
+
- ok
|
|
19915
19961
|
ConnectorFetchInput:
|
|
19916
19962
|
type: object
|
|
19917
19963
|
properties:
|
|
@@ -26251,6 +26297,12 @@ components:
|
|
|
26251
26297
|
type: string
|
|
26252
26298
|
totalSynced:
|
|
26253
26299
|
type: number
|
|
26300
|
+
circuitOpenedAt:
|
|
26301
|
+
type: string
|
|
26302
|
+
circuitProbeAt:
|
|
26303
|
+
type: string
|
|
26304
|
+
circuitReason:
|
|
26305
|
+
type: string
|
|
26254
26306
|
required:
|
|
26255
26307
|
- id
|
|
26256
26308
|
- orgId
|
|
@@ -26267,6 +26319,47 @@ components:
|
|
|
26267
26319
|
- createdBy
|
|
26268
26320
|
- createdAt
|
|
26269
26321
|
- updatedAt
|
|
26322
|
+
FailedRecord:
|
|
26323
|
+
type: object
|
|
26324
|
+
properties:
|
|
26325
|
+
id:
|
|
26326
|
+
type: string
|
|
26327
|
+
entityId:
|
|
26328
|
+
type: string
|
|
26329
|
+
externalId:
|
|
26330
|
+
type: string
|
|
26331
|
+
status:
|
|
26332
|
+
type: string
|
|
26333
|
+
enum:
|
|
26334
|
+
- failed
|
|
26335
|
+
- dead
|
|
26336
|
+
attempts:
|
|
26337
|
+
type: number
|
|
26338
|
+
nextAttemptAt:
|
|
26339
|
+
type: string
|
|
26340
|
+
lastError:
|
|
26341
|
+
type: string
|
|
26342
|
+
updatedAt:
|
|
26343
|
+
type: string
|
|
26344
|
+
required:
|
|
26345
|
+
- id
|
|
26346
|
+
- status
|
|
26347
|
+
- attempts
|
|
26348
|
+
FailedRecordList:
|
|
26349
|
+
type: object
|
|
26350
|
+
properties:
|
|
26351
|
+
direction:
|
|
26352
|
+
$ref: "#/components/schemas/FlowDirection"
|
|
26353
|
+
items:
|
|
26354
|
+
type: array
|
|
26355
|
+
items:
|
|
26356
|
+
$ref: "#/components/schemas/FailedRecord"
|
|
26357
|
+
nextCursor:
|
|
26358
|
+
type: string
|
|
26359
|
+
required:
|
|
26360
|
+
- direction
|
|
26361
|
+
- items
|
|
26362
|
+
- nextCursor
|
|
26270
26363
|
CreateFlowInput:
|
|
26271
26364
|
type: object
|
|
26272
26365
|
properties:
|
|
@@ -26338,6 +26431,8 @@ components:
|
|
|
26338
26431
|
type: number
|
|
26339
26432
|
skipped:
|
|
26340
26433
|
type: number
|
|
26434
|
+
held:
|
|
26435
|
+
type: number
|
|
26341
26436
|
status:
|
|
26342
26437
|
$ref: "#/components/schemas/RunStatus"
|
|
26343
26438
|
runId:
|
|
@@ -26734,7 +26829,8 @@ components:
|
|
|
26734
26829
|
- testConnection
|
|
26735
26830
|
- describeTarget
|
|
26736
26831
|
- sample
|
|
26737
|
-
-
|
|
26832
|
+
- shape
|
|
26833
|
+
- serialize
|
|
26738
26834
|
RunTrigger:
|
|
26739
26835
|
type: string
|
|
26740
26836
|
enum:
|