You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Re-mirror the specification and changelog for new Section 6.3, re-copy
the schema with its updated TemplateURL description, and regenerate the
schema page embeds and its TemplateURL type reference.
Copy file name to clipboardExpand all lines: docs/changelog.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
14
14
15
15
### Changed
16
16
17
+
- 2026-07-21 — New Section 6.3 (Template Sources) makes explicit that a template URL is an identifier first and a fetchable location only secondarily: clients MAY satisfy template URLs from any source — an application bundle, templates shipped with the page, a BFF-local store or template service, or a network fetch — all equally conforming, with the absolute URL (Section 5.4) as the template's identity and cache key. The Section 2 Template URL definition, Section 8 algorithm ("obtain" rather than "fetch" templates), Section 10 (its requirements now explicitly scoped to network retrieval), Section 15.2 client conformance, and the schema's TemplateURL description were aligned accordingly.
17
18
- 2026-07-21 — All example template URLs consolidated onto a single host: `https://example.com/templates/...` replaces the `templates.example.com` subdomain throughout the specification and examples. Template URLs are identifiers first; a dedicated template host in every example suggested a deployment choice (a separate template server) that the protocol does not make.
18
19
- 2026-07-21 — JSON Schemas upgraded from draft-07 to the [JSON Schema 2020-12](https://json-schema.org/specification-links#2020-12) dialect (`$schema` is now `https://json-schema.org/draft/2020-12/schema`). The schemas already used the post-draft-07 `$defs` keyword, so the declared dialect now matches the keywords in use; no other schema changes were needed. CI and local validation pass `--spec=draft2020` to ajv. The archived RVST schemas remain draft-07.
19
20
- 2026-07-20 — Optional template metadata on view descriptors (new Section 3.6): an advisory `type` member (media type hint for the template resource) and an `integrity` member (W3C Subresource Integrity); an integrity mismatch is treated as a template fetch failure.
Copy file name to clipboardExpand all lines: docs/schema.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -67,7 +67,7 @@ Because the schemas are hosted at their `$id` URLs, they can be referenced direc
67
67
"TemplateURL": {
68
68
"type": "string",
69
69
"format": "uri",
70
-
"description": "A URL identifying a template resource. MUST use HTTPS (loopback addresses excepted for local development)."
70
+
"description": "A URL identifying a template. The URL is an identifier first — which source supplies the template (app bundle, page, BFF-local store, network fetch) is deployment-specific and outside the protocol. Network retrieval MUST use HTTPS (loopback addresses excepted for local development)."
71
71
},
72
72
73
73
"Slots": {
@@ -193,7 +193,7 @@ The core type. Identifies a root template and optionally declares slot assignmen
193
193
194
194
### TemplateURL
195
195
196
-
A URI string (`format: "uri"`) identifying a template resource. MUST use HTTPS in production.
196
+
A URI string (`format: "uri"`) identifying a template. The URL is an identifier first — which source supplies the template (app bundle, page-shipped templates, BFF-local store, network fetch) is deployment-specific and outside the protocol (Specification Section 6.3). Network retrieval MUST use HTTPS in production.
Copy file name to clipboardExpand all lines: docs/schemas/vdp.v0-1.schema.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -53,7 +53,7 @@
53
53
"TemplateURL": {
54
54
"type": "string",
55
55
"format": "uri",
56
-
"description": "A URL identifying a template resource. MUST use HTTPS (loopback addresses excepted for local development)."
56
+
"description": "A URL identifying a template. The URL is an identifier first — which source supplies the template (app bundle, page, BFF-local store, network fetch) is deployment-specific and outside the protocol. Network retrieval MUST use HTTPS (loopback addresses excepted for local development)."
Copy file name to clipboardExpand all lines: docs/specification.md
+22-5Lines changed: 22 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,7 +25,7 @@ REST APIs return structured data (JSON, XML) that carries no presentation inform
25
25
## 2. Terminology
26
26
27
27
-**View Descriptor**: A JSON object that describes a template tree — a root template URL and its slot assignments.
28
-
-**Template URL**: A URL identifying a template resource. The URL MUST resolve to a renderable template in the client's rendering framework.
28
+
-**Template URL**: A URL identifying a template. The URL is an *identifier* first — a stable name and namespace for the template, and the key under which the client caches it — and a fetchable location only secondarily (Section 6.3). Through whatever source the deployment uses, it MUST resolve to a renderable template in the client's rendering framework.
29
29
-**Slot**: A named insertion point in a template where a sub-template can be composed. Slot names correspond to the template's own insertion point identifiers (e.g., Qute's `{#insert slotName}`).
30
30
-**View Descriptor Resource**: A standalone JSON document containing a view descriptor, addressable by its own URL, cacheable independently of the data it describes.
31
31
-**Static Composition**: Composition written directly into a template's source — for example, a layout that always includes its `_head` partial. VDP does not describe static composition; it is internal to the template.
@@ -438,6 +438,21 @@ VDP is agnostic to the template language. However, a template used with VDP MUST
438
438
439
439
Not every insertion point in a template needs to appear in the view descriptor. Templates commonly include partials that never change — a shared `_head`, a footer — and those stay hardcoded in the template (static composition, Section 2). Only slots whose content varies per API response belong in the view descriptor (dynamic composition).
440
440
441
+
### 6.3 Template Sources
442
+
443
+
A template URL names *which* template renders a slot. Deliberately, VDP does not define where the template's source text comes from: the URL is an identifier first — a stable name and namespace for the template, much like a package import path — and the key under which the client caches it. How a client turns that identifier into template source text is a deployment decision, outside the protocol.
444
+
445
+
A client MAY satisfy a template URL from any source, including:
446
+
447
+
- templates bundled into the application package (typical for mobile and desktop clients);
448
+
- templates shipped with the page itself (for browsers — e.g., `<template>` elements delivered with the initial HTML);
449
+
- a store local to the BFF, or a dedicated template service;
450
+
- a network fetch of the template URL itself.
451
+
452
+
All of these are equally conforming. Whatever the source, the client MUST select templates by the absolute URL produced by the Section 5.4 resolution rules — the URL is the template's identity, so a template satisfied from a local source is indistinguishable, to the rest of the resolution algorithm, from a fetch whose cache was already warm (Section 5.2). Fetching the URL over the network is the interoperable default when no local source provides the template, and every network retrieval is subject to Section 10.
453
+
454
+
The `integrity` member (Section 3.6) authenticates template content obtained from outside the client's trust boundary. A client MAY skip integrity verification for templates satisfied from its own bundle; when integrity metadata is present, it MUST verify any template it fetches over the network (Section 3.6).
455
+
441
456
## 7. Examples
442
457
443
458
### 7.1 Login Page (Simple, No Slots)
@@ -573,11 +588,11 @@ This is the pattern used by **quarkus-pha**: Quarkus acts as the BFF, fetching d
573
588
574
589
1.**Extract view descriptor** from the response (check `_view`/`_views` body key, then `Link` header, then `View-Template` header).
575
590
2.**Fetch the view descriptor** if it is a URL reference (cache as appropriate).
576
-
3.**Fetch the root template**from the `template` URL, verifying `integrity` when present (Section 3.6).
591
+
3.**Obtain the root template**identified by the `template` URL, from any Section 6.3 source, verifying `integrity` when present (Section 3.6).
577
592
4.**Identify slot insertion points** in the template.
578
593
5.**For each slot** declared in the view descriptor:
579
594
a. If the slot value is a descriptor reference (Section 3.7), fetch the referenced view descriptor resource and substitute the result; on failure or cycle, handle per Section 9.1.
580
-
b. Fetch the sub-template from its `template` URL, verifying `integrity` when present.
595
+
b. Obtain the sub-template identified by its `template` URL, verifying `integrity` when present.
581
596
c. If the slot's view descriptor itself declares `slots`, repeat steps 3–5 for that descriptor.
582
597
d. Insert the resolved sub-template into the slot.
583
598
6.**Render** the composed template tree with the API response data.
@@ -629,6 +644,8 @@ Error handling follows the principle that a failure stays as local as possible:
629
644
630
645
## 10. Security Considerations
631
646
647
+
The requirements in this section govern templates and descriptors **retrieved over a network**. A client that satisfies template URLs from a source inside its own trust boundary (Section 6.3) — an application bundle, templates shipped with the page, a BFF-local store — need not apply them to those templates; any retrieval that does cross the network remains subject to them in full.
648
+
632
649
-**Template URL validation**: Clients MUST validate template URLs against an allowlist of trusted URL prefixes. Rendering arbitrary templates from untrusted sources is a code injection risk. The allowlist is determined by the first available source below:
633
650
1.**Local configuration** — an allowlist configured in the client or its deployment. When present, it takes precedence over anything the server advertises.
634
651
2.**Discovery document** — the `trustedTemplateUrls` member of the API's discovery document (Section 13.2), when one is available.
@@ -640,7 +657,7 @@ Error handling follows the principle that a failure stays as local as possible:
640
657
-**CORS**: Template resources served cross-origin MUST include appropriate CORS headers.
641
658
-**Content Security Policy**: Browser clients fetching templates at runtime SHOULD include template origins in the `connect-src` CSP directive. `script-src` or `style-src` apply only where templates are loaded as executable scripts or stylesheets.
642
659
-**Template sandboxing**: Clients SHOULD render templates in a sandboxed context to prevent template injection attacks.
643
-
-**HTTPS**: Template URLs MUST use HTTPS. Clients SHOULD reject `http:` template URLs, with an exception permitted for loopback addresses during local development.
660
+
-**HTTPS**: Templates retrieved over a network MUST be retrieved via HTTPS. Clients SHOULD reject fetching`http:` template URLs, with an exception permitted for loopback addresses during local development.
644
661
645
662
## 11. Relationship to Existing Standards
646
663
@@ -875,7 +892,7 @@ Software that consumes view descriptors and resolves template trees. A conformin
875
892
- MUST extract view descriptors using the precedence order of Section 4.4.
876
893
- MUST implement the resolution algorithm of Section 8, including a recursion depth limit and reference cycle handling.
877
894
- MUST implement the error handling behavior of Section 9 — in particular, preferring partial rendering over total failure.
878
-
- MUST validate template URLs against the allowlist source chain of Section 10 and reject non-HTTPS template URLs outside local development.
895
+
- MUST apply the Section 10 requirements — the allowlist source chain, HTTPS — to every template it retrieves over a network; templates satisfied from a source inside its own trust boundary (Section 6.3) are exempt.
879
896
- MUST reject invalid view descriptors (Section 9.3) rather than attempting partial interpretation of them.
880
897
- SHOULD verify template `integrity` metadata when present (Section 3.6).
881
898
- MUST ignore unrecognized members of the discovery document (Section 13.2).
0 commit comments