Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
ReSpec makes it easier to write technical documents. It was originally designed for writing W3C specifications, but now supports many output formats.
A ReSpec document is an HTML file that brings in the ReSpec script, defines a configuration object, and follows a few conventions. Open it in a browser over HTTP and ReSpec transforms it into a properly formatted specification.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My API</title>
<script
src="https://www.w3.org/Tools/respec/respec-w3c"
class="remove"
async
></script>
<script class="remove">
var respecConfig = {
specStatus: "ED",
editors: [{ name: "Your Name", url: "https://your-site.example/" }],
github: "some-org/mySpec",
shortName: "my-api",
xref: "web-platform",
group: "my-working-group",
};
</script>
</head>
<body>
<section id="abstract">
<p>This spec defines the My API.</p>
</section>
<section id="sotd"></section>
<section class="informative">
<h2>Introduction</h2>
<p>Some introductory text.</p>
<aside class="note" title="A note">
<p>Notes look like this.</p>
</aside>
</section>
<section data-dfn-for="Foo">
<h2>The <code>Foo</code> interface</h2>
<pre class="idl">
[Exposed=Window]
interface Foo {
attribute DOMString bar;
undefined doTheFoo();
};
</pre>
<p>The <dfn>Foo</dfn> interface represents a {{Foo}}.</p>
<p>The <dfn>doTheFoo()</dfn> method does the foo. Call it via {{Foo/doTheFoo()}}.</p>
<ol class="algorithm">
<li>Let |result:DOMString| be a new string.</li>
<li>Return |result|.</li>
</ol>
</section>
<section id="conformance"></section>
</body>
</html>
Preview it: Open the file via a local HTTP server — not file:// (browsers block fetches from file://):
# Any of these work:
npx serve .
python3 -m http.server
Then open http://localhost:PORT/your-spec.html.
Add these two <script> elements to the <head>. The class="remove" ensures they are stripped from the exported static HTML.
<script
src="https://www.w3.org/Tools/respec/respec-w3c"
class="remove"
async
></script>
<script class="remove">
// var is required — ReSpec reads this as window.respecConfig
// (const/let are block-scoped and not visible to the ReSpec bundle)
var respecConfig = {
// configuration options
};
</script>
Note: var is required — ReSpec reads this as window.respecConfig. const or let would not be visible to the ReSpec bundle.
ReSpec is continuously updated. Loading it from w3.org/Tools/respec/ means you automatically get the latest bug fixes and features.
All configuration options are documented in this reference. The minimum required options are specStatus and editors. For W3C working group documents, also set group.
var respecConfig = {
specStatus: "ED",
editors: [{ name: "Your Name", url: "https://your-site.example/" }],
};
Configuration can also be overridden via URL query params — useful for generating snapshots without editing the source: index.html?specStatus=WD&publishDate=2025-06-01.
ReSpec documents are HTML. They use standard HTML structural elements with a few conventions.
Set the document title using the <title> element. ReSpec uses it to generate the <h1> heading.
<title>Payment Request API</title>
If you need markup in the title (e.g., <code>), use <h1 id="title"> instead. See <h1 id="title">.
Add a subtitle either in config or as markup:
var respecConfig = {
subtitle: "Level 2",
};
<h2 id="subtitle">Level 2</h2>
Wrap content in <section> elements. ReSpec handles numbering, IDs, and ToC entries automatically.
<section>
<h2>Concepts</h2>
<p>Some text.</p>
<section class="informative">
<h3>Background</h3>
<p>Non-normative background text.</p>
</section>
</section>
Empty links to a section's ID auto-fill with "§ N.N Title":
<p>As described in <a href="#concepts"></a>...</p>
<!-- Renders: As described in § 2 Concepts... -->
Section classes: informative, appendix, notoc.
Generated automatically after the SotD section. Control depth with maxTocLevel. Suppress with noTOC: true.
<figure id="fig-overview">
<img src="overview.svg" alt="System overview diagram" />
<figcaption>System overview.</figcaption>
</figure>
<p>See <a href="#fig-overview"></a> for the system overview.</p>
<!-- Renders: See Figure 1 for... -->
Generate a Table of Figures with <section id="tof">.
<aside class="example" title="Using the API">
<pre class="js">
const result = await navigator.credentials.get();
</pre>
</aside>
<div class="note">
<p>Implementations should handle the error case.</p>
</div>
<p class="issue" data-number="42">
<!-- Content of GitHub issue #42 is embedded automatically -->
</p>
Code inside <pre> is automatically syntax-highlighted using highlight.js. Specify the language with a class:
<pre class="js">const x = 1;</pre>
<pre class="css">.widget { color: red; }</pre>
<pre class="webidl">interface Foo {};</pre>
Use class="nohighlight" to disable. Use class="nolinks" to prevent URLs from becoming hyperlinks.
<section data-include="sections/api.html"></section>
<section data-include="sections/intro.md"
data-include-format="markdown"></section>
Requires HTTP — file:// URLs will fail due to browser CORS restrictions. See data-include.
<section id="conformance">
<!-- RFC 2119 boilerplate added automatically -->
<p>Additional conformance text here.</p>
</section>
Required for specs with normative requirements. Adds RFC 2119 keyword definitions (MUST, SHOULD, MAY, etc.).
<p>The <abbr title="World Wide Web Consortium">W3C</abbr> develops web standards.</p>
<!-- All subsequent occurrences of "W3C" are automatically wrapped in <abbr> -->
Or use data-abbr on a <dfn> to auto-generate abbreviations.
<p>The <dfn>fetch</dfn> algorithm retrieves a resource.</p>
<p>Run the [=fetch=] algorithm.</p>
<p>Run the <a>fetch</a> algorithm.</p>
<!-- Both produce: Run the fetch algorithm (as a link) -->
<dfn>request</dfn>
<!-- All of these link correctly: -->
<a>request</a>
<a>requests</a>
[=request=]
[=requests=]
<dfn data-lt="user agent|browser">user agent</dfn>
<!-- All link to the same definition: -->
[=user agent=] [=browser=]
See data-lt.
Enable xref and write terms naturally — ReSpec finds them automatically:
var respecConfig = {
xref: "web-platform", // includes HTML, Infra, URL, WebIDL, DOM, Fetch
};
<p>
[=Queue a task=] to [=fire an event=] named "load"
at the {{Window}} object.
</p>
Browse available terms at respec.org/xref.
| Syntax | Links to |
|---|---|
[=term=] |
Concept or abstract term |
{{Interface}} |
WebIDL interface |
{{Interface/member}} |
WebIDL member |
[^element^] |
HTML/SVG element |
[[SPEC]] |
Informative bibliography reference |
[[!SPEC]] |
Normative bibliography reference |
[[[#section-id]]] |
Section in this document |
[[[SPEC#section-id]]] |
Section in another spec |
See the Shorthands Guide for full syntax.
The [^link^] element is defined in [[HTML]].
This MUST NOT be done per [[!RFC2119]].
ReSpec auto-generates a References section from all [[SPEC]] citations. Spec IDs come from Specref — which includes most W3C, WHATWG, ECMA, and IETF documents.
For a non-normative reference in a normative section, use [[?SPEC]].
To add a missing reference, contribute it to Specref or use localBiblio.
ReSpec infers from context: references in informative sections, notes, examples, or figures become informative automatically. References in normative sections are normative.
var respecConfig = {
group: "webapps", // see respec.org/w3c/groups/ for shortnames
};
group configures patent policy, group homepage, and mailing list automatically. It replaces the old wg, wgId, wgURI, wgPatentURI, and wgPublicList options.
specStatus sets the document maturity level. Common values:
| Value | Description |
|---|---|
"ED" |
Editor's Draft (default — for active development) |
"WD" |
Working Draft |
"CR" |
Candidate Recommendation |
"REC" |
Recommendation |
"CG-DRAFT" |
Community Group Draft |
See specStatus for the full list.
For TR/ publication:
var respecConfig = {
specStatus: "WD",
publishDate: "2025-06-15",
previousPublishDate: "2024-12-01",
previousMaturity: "FPWD",
group: "webapps",
shortName: "my-api",
};
Export to static HTML first (ReSpec pill → Save as HTML), then submit via Echidna or the W3C publication tools.
By default, W3C specs use the standard W3C copyright and the group's patent policy (set via group).
To modify: use license, copyrightStart, or additionalCopyrightHolders.
Add custom patent notes directly into <section id="sotd">.
To specify an interface using WebIDL, you define a <pre class="idl"> block.
<pre class="idl">
interface Request {
readonly attribute ByteString method;
readonly attribute USVString url;
};
</pre>
The recommended pattern is a <section data-dfn-for="InterfaceName"> that groups the IDL block with prose definitions for each member:
<section data-dfn-for="Fetch">
<h2>The <code>Fetch</code> interface</h2>
<pre class="idl">
[Exposed=Window]
interface Fetch {
constructor(USVString url);
readonly attribute USVString url;
undefined send();
};
</pre>
<section>
<h2>Constructors</h2>
<p>The <dfn constructor for="Fetch">constructor(url)</dfn> steps are:</p>
<ol class="algorithm">
<li>Set [=this=]'s {{Fetch/url}} to |url|.</li>
</ol>
</section>
<section>
<h2>Attributes</h2>
<p>The <dfn attribute>url</dfn> attribute steps are to return [=this=]'s url.</p>
</section>
<section>
<h2>Methods</h2>
<p>The <dfn method>send()</dfn> method steps are:</p>
<ol class="algorithm">
<li>...</li>
</ol>
</section>
</section>
data-dfn-for📝 Editdata-dfn-for on a <section> sets the default interface context for all <dfn> elements within it. This saves repeating the interface name on every definition:
<section data-dfn-for="Request">
<p>The <dfn>url</dfn> attribute of {{Request}}.</p>
<p>The <dfn>clone()</dfn> method.</p>
<!-- Both dfns are automatically "for Request" -->
</section>
Without data-dfn-for, use explicit for= attributes on individual <dfn> elements.
Define constructors with <dfn constructor for="InterfaceName">:
<p>The <dfn constructor for="Widget">constructor(name, options)</dfn> steps are:</p>
<ol class="algorithm">
<li>Let |w:Widget| be a new {{Widget}} object.</li>
<li>Set |w|'s {{Widget/name}} to |name|.</li>
<li>Return |w|.</li>
</ol>
Link to the constructor from prose: {{Widget/constructor(name, options)}}.
Enum values defined in the IDL block are automatically linked. To add prose descriptions, define them explicitly using data-dfn-type="enum-value" and data-dfn-for:
<pre class="idl">
enum RequestMode { "navigate", "cors", "no-cors", "same-origin" };
</pre>
<p>The <dfn data-dfn-type="enum-value" data-dfn-for="RequestMode">"cors"</dfn>
mode means cross-origin requests are sent with CORS headers.</p>
<p>The <dfn data-dfn-type="enum-value" data-dfn-for="RequestMode">"navigate"</dfn>
mode is used for top-level navigation.</p>
Link to enum values in prose: {{RequestMode/"cors"}}.
Dictionary members defined in IDL are automatically linked. Reference them in prose as {{DictionaryName/memberName}}:
<pre class="idl">
dictionary RequestInit {
ByteString method = "GET";
boolean keepalive = false;
};
</pre>
<p>If |init|'s {{RequestInit/method}} is not a [=method=], throw a {{TypeError}}.</p>
If two interfaces share attribute or method names, use data-dfn-for to distinguish them:
<section data-dfn-for="Request">
<p>The <dfn>url</dfn> attribute of {{Request}}.</p>
</section>
<section data-dfn-for="Response">
<p>The <dfn>url</dfn> attribute of {{Response}}.</p>
</section>
When defining IDL members as prose <dfn> elements, you can omit data-dfn-type when data-dfn-for is set on the containing section — ReSpec infers the type from the IDL. For explicit control:
| Pattern | Type inferred |
|---|---|
<dfn attribute>url</dfn> |
attribute |
<dfn method>send()</dfn> |
method |
<dfn constructor for="Foo">constructor()</dfn> |
constructor |
<dfn data-dfn-type="dict-member">method</dfn> |
dict-member |
<pre class="idl"> block is syntax-highlighted and validated by ReSpecclass="exclude" on a <pre class="idl"> to keep it out of the IDL index: <pre class="idl exclude">Open the ReSpec UI and select "Export...".
Select the format to export as.
One off (downloads about 100mb)...
npx respec --src source.html --out index.html
Or, to install ReSpec for repeated use:
npm install --global respec
And then:
respec --src source.html --out index.html
For more options, run respec --help.
Description
Converts a ReSpec source file to HTML and writes to destination.
Usage
$ respec [source] [destination] [options]
Options
-s, --src URL to ReSpec source file.
-o, --out Path to output file.
-t, --timeout How long to wait before timing out (in seconds). (default 10)
--use-local Use locally installed ReSpec instead of the one in document. (default false)
-e, --haltonerror Abort if the spec has any errors. (default false)
-w, --haltonwarn Abort if ReSpec generates warnings. (default false)
--disable-sandbox Disable Chromium sandboxing if needed. (default false)
--devtools Enable debugging and show Chrome's DevTools. (default false)
--verbose Log processing status to stdout. (default false)
--localhost Spin up a local server to perform processing. (default false)
--port Port override for --localhost. (default 3000)
-v, --version Displays current version
-h, --help Displays this message
Similar to markdown, shorthands trigger special behavior in ReSpec. The most commonly used one you've likely seen is [[Reference]]. Shorthands save you time and work: you write a lot less HTML, and ReSpec does all the linking and error checking for you.
Each of these special character combinations, as well as what behavior they trigger, are detailed below.
Note: Only WebIDL identifiers are case sensitive.
| Type | Syntax | Examples |
|---|---|---|
| WebIDL | {{WebIDLThing}} |
{{PaymentRequest}} {{PaymentRequest/show()}} |
| Concepts in specs | [=normal link=] |
[=queue a task=] |
| Variable in an algorithm | |variable:Type| |
Let |p:Promise| be a new {{Promise}} |
| HTML/SVG elements | [^element^] |
[^iframe^] |
| Element attributes | [^element/attribute^] |
[^iframe/allow^] |
| References | [[shortName]] |
[[RFC2119]] |
| Expansions | [[[#some-id]]] |
[[[#example-2]]] expands and links to "Example 2" |
By design, we also share a lot of syntax with the BikeShed document processor. This makes it easier for everyone in the standards community to edit ReSpec and BikeShed specifications.
WebIDL is a meta language that used to define Javascript APIs for Web browsers. Please see our WebIDL Guide or the WebIDL spec for more info.
To link to something in WebIDL, you need to know its identifier. An identifier is the name of the interface, dictionary, or enum.
For example, {{PaymentRequest}} links to the PaymentRequest interface.
You can link attributes, methods, or members by using the interface name, /, and the name of the thing you want to link to. For example, {{PaymentRequest/show()}} links to the show() operation of the PaymentRequest interface.
| Type | Syntax | Examples |
|---|---|---|
| Interface, Dictionary, Enum or IDL type | {{Identifier}} |
{{PaymentRequest}} {{unrestricted double}} {{long long}} |
| Attribute | {{Identifier/attributeName}} |
{{PaymentRequest/id}} |
| Operation or Method | {{Identifier/methodName()}} {{Identifier/methodName(someArg)}} |
{{PaymentRequest/show()}} {{PaymentRequest/show(detailsPromise)}} |
| Static Attribute | {{Identifier.attribute}} |
{{SomeInterface.someAttribute}} |
| Static Operation or Static Method | {{Identifier.methodName()}} {{Identifier.methodName(arg)}} |
{{URL.createObjectURL()}} {{URL.createObjectURL(obj)}} |
| Enum Value | {{Identifier/"value"}} |
{{PaymentComplete/"success"}} |
| DOM Exception | {{"Identifier"}} |
{{"NotAllowedError"}} |
Warning: Aliasing is not recommended.
You can alias WebIDL method names if you think the original name is adding noise.
| Input | Renders as |
|---|---|
{{ Window/postMessage(message, options) }} |
postMessage(message, options) |
{{ Window/postMessage(message, options)|postMessage(message) }} |
postMessage(message) |
{{ Window/postMessage(message, options)|postMessage() }} |
postMessage() |
{{ Window/postMessage(message, options)|postMessage }} |
postMessage() |
Concepts include: ideas, named algorithms, useful terms, and/or non-webIDL things that are defined in a spec.
Basically, "defined" means that a thing is within <dfn> tags. For example, <dfn>success</dfn> and <dfn>the steps to make a great meal</dfn> are defined concepts.
The syntax is [=concept you want to link to=]. For example, [=queue a task=] and [=fire an event=].
To link to a concept in another spec, you need to use the xref configuration option, and simply cite the spec you want to link to:
<p data-cite="HTML DOM">
You can [=queue a task=] to [=fire an event=] named `"respec-is-amazing"`.
</p>
In the above, "queue a task" is defined in the HTML specification while "fire and event" is defined in the DOM specification.
See xref for more information.
ReSpec supports automatically linking to plural forms for simple nouns. Thus, [=fruits=] links to the singular concept of fruit, even across specs.
Warning: Aliasing is not recommended.
Always try to adapt your text to a defined concept, and only use an alias if absolutely needed! This keeps specs consistent and keeps things easier to find across specs.
Having said that, sometimes [=convoluted thing=] might be confusing or not make sense in the context of your spec. In such cases, use a pipe | to "alias" a given concept into something that better fits the flow of your spec.
For example, with [=convoluted thing|simpler thing=], simpler thing will be the text on your spec. It will link to convoluted thing.
Another reason is that the definition’s default name does not grammatically fit into your sentence. For example, your definition is [=queue a task=] but you are giving an example of "task queuing". Alias the concept with [=queue a task|task queuing=] (again, don't do this! fix your spec instead or talk to the other editors of the other spec to export a more sane definition 🙇♂️).
| Type | Syntax | Examples |
|---|---|---|
| Concept | [=concept=] |
[=queue a task=] |
| Aliased concept | [=concept|some alias=] [=convoluted thing|simpler thing=] |
[=queue a task|task queuing=] |
Just as WebIDL interfaces can have methods and attributes, concepts have a very specific relationship to each other.
For example, the definition of a forEach() method for a list behaves differently from the definition of forEach() method for a map: the former operates on a single item, while the letter operates on a key/value pair. To make the relationship clear, we would write [=map/for each=], which is different to, say, [=list/for each=].
To associate a concept with another concept, use data-dfn-for to indicate who or what owns the concept. This tells Respec who or what the concept is "for". See the example below:
A <dfn>car</dfn> has a <dfn data-dfn-for="car">engine</dfn>, which burns petroleum.
A <dfn>browser</dfn> has a <dfn data-dfn-for="browser">engine</dfn>, which burns
democracy.
| Type | Syntax | Examples |
|---|---|---|
| Concept for thing | [=concept/sub concept=] |
[=list/for each=] [=map/for each=] [=Document/visible=] |
The syntax is |name|, where name is the name of the variable.
Let |value| be the {{DOMString}} "hello". ... If |value| is not "hello", then
do…
Add : and the data type after the variable's name.
For example, |value:DOMString| tells Respec that the variable value is of type {{DOMString}}.
ReSpec tracks declared variables within algorithms, allowing users to click on them to have them highlighted.
This helps readers know where variables were declared and where they are used. If the variable has is type information, ReSpec also propagates this throughout an algorithm. When a reader hovers over a variable, Respec presents information about the variable's type (see an example - GIF, 2.8MB).
| Type | Syntax | Examples |
|---|---|---|
| Variable | |variable| |
|value| |
| Variable with a data type | |variable:dataType| |
|value:DOMString| |
To reference HTML elements, use the following syntax: [^tagname^]. * Here, the tagname is a valid HTML tag that is defined in the HTML spec or some other spec that defines the tag.
You can also link to particular content attributes of HTML elements by using a / after then tag name, followed by the name of the attribute you'd like to link to.
For example, [^iframe/allow^] links to the allow attribute for an iframe in the HTML spec.
| Type | Syntax | Examples |
|---|---|---|
| Element | [^element^] |
[^iframe^] |
| Element with Content Attribute | [^element/contentAttribute^] |
[^iframe/allow^] |
Note: To link to an IDL attribute on a HTML element's interface, which is different from an element attribute, you would do, for example {{HTMLIframeElement/allow}}.
To reference another specification, just write [[FOO]] - where FOO is the short name or id of a specification. If you are don't know the the short name or id, please search for the spec at SpecRef.
| Type | Syntax | Examples |
|---|---|---|
| Normal Reference | [[SHORTNAME]] |
[[HTML]] |
| Expanded Reference | [[[SHORTNAME]]] |
[[[FULLSCREEN]]], [[[fullscreen API]]] are expanded and rendered as Full Screen API |
| Cross-spec section link | [[[SHORTNAME#id]]] |
[[[fetch#data-fetch]]] renders as a link to that section with the spec title as text |
| Informative spec | [[?SHORTNAME]] |
Payments can be useful [[?PAYMENT-REQUEST]]. |
| Escaped reference | [[\anything]] |
This is not a reference. It is [[\something else]]. |
| Inner-document expansion | [[[#fragment]]] |
See [[[#installability-signals]]] is expanded and rendered as See § 2.6 Installability signals. |
| Multi-page reference | [[SHORTNAME/page#fragment]] |
[[SOMESPEC/foo.html#bar]] (Not recommended, use only if you really need it!) |
ReSpec supports GitHub Flavored Markdown (GFM) for writing specification content.
var respecConfig = {
format: "markdown",
};
With format: "markdown", the entire <body> is treated as Markdown. Keep all content flushed to the left — whitespace is significant in Markdown.
<section data-include="my-section.md"
data-include-format="markdown"></section>
Markdown headings create nested <section> elements automatically:
## Introduction
Some text.
### Background
More text.
## My Heading {#my-custom-id}
An image with a title becomes a <figure> with <figcaption>:

Use triple-backtick fences with a language hint:
```js
async function fetchData() {
return await fetch("/api/data.json");
}
```
For WebIDL blocks:
```webidl
[Exposed=Window]
interface Example {
undefined doThing();
};
```
HTML elements and Markdown can be mixed, but require a blank line between the tag and the content:
<div class="note">
This is **Markdown** inside an HTML element.
</div>
class="nolinks" to the <pre> elementaddSectionLinks📝 EditType: boolean
Default: true
Controls whether § self-link markers are added to section headings, allowing users to link directly to a section.
var respecConfig = {
addSectionLinks: false,
};
§) appear on hover next to each heading§ link copies the section URL to the clipboard (or navigates to it)caniuse📝 EditType: string | CaniuseOptions
Default: undefined
Adds a browser support table to the document header, sourced from caniuse.com.
var respecConfig = {
caniuse: "payment-request",
};
var respecConfig = {
caniuse: {
feature: "payment-request",
browsers: ["chrome", "firefox", "safari", "edge"],
},
};
| Option | Type | Default | Description |
|---|---|---|---|
feature |
string |
required | caniuse.com feature key (the slug from the URL) |
browsers |
string[] |
all major | Browser IDs to include in the table |
removeOnSave |
boolean |
true |
Strip the widget when saving as HTML; replace with a link to caniuse.com |
apiURL |
string |
caniuse data on respec.org | Override the caniuse data endpoint — advanced use, e.g. self-hosted data |
| ID | Browser |
|---|---|
chrome |
Chrome |
edge |
Edge |
firefox |
Firefox |
safari |
Safari |
ios_saf |
Safari on iOS |
and_chr |
Chrome on Android |
and_ff |
Firefox on Android |
and_uc |
UC Browser on Android |
samsung |
Samsung Internet |
op_mob |
Opera Mobile |
opera |
Opera |
https://caniuse.com/FEATURE-KEYwf-* prefixed features (Baseline/web-features) are not yet supported — they come from a different data sourceedDraftURI📝 EditType: string
Default: auto-generated from github and shortName
The URL of the Editor's Draft. Shown in the document header as a "This version" or "Latest editor's draft" link.
var respecConfig = {
specStatus: "ED",
edDraftURI: "https://w3c.github.io/payment-request/",
};
github is set, edDraftURI is automatically derived from the repo — you usually don't need to set it manuallynull to suppress the link: edDraftURI: nullhttps://w3c.github.io/short-name/)editors📝 EditType: Person[]
Default: []
An array of person objects describing the editors of the document. At least one editor is required for most W3C documents.
var respecConfig = {
editors: [
{
name: "Alice Smith",
url: "https://example.org/alice",
company: "Example Corp",
companyURL: "https://example.org/",
w3cid: 12345,
},
{
name: "Bob Jones",
company: "Another Co.",
companyURL: "https://anotherco.example/",
w3cid: 67890,
},
],
};
| Field | Type | Description |
|---|---|---|
name |
string |
Required. Full name of the editor |
url |
string |
Personal URL or mailto: address |
company |
string |
Employer or affiliation |
companyURL |
string |
URL of the employer |
w3cid |
number |
W3C account ID — enables contributor stats |
orcid |
string |
ORCID iD URL (e.g. https://orcid.org/0000-0000-0000-0000) |
note |
string |
Short note shown in parentheses after the name |
extras |
Extra[] |
Additional links shown after the person entry |
retiredDate |
string |
"YYYY-MM-DD" — marks editor as having retired on this date |
extras formatformerEditors, or set retiredDate to keep them listed inlineauthorsformat📝 EditType: "markdown" | "html"
Default: "html"
Sets the content format for the entire document body. When set to "markdown", ReSpec interprets the document body as GitHub Flavored Markdown.
var respecConfig = {
format: "markdown",
};
data-include-format="markdown" instead of setting this globallyformat: "markdown", keep all text flushed to the left — Markdown is whitespace-sensitiveformerEditors📝 EditType: Person[]
Default: []
An array of person objects listing past editors of the document. Shown below the current editors list.
var respecConfig = {
editors: [
{ name: "Alice Smith", company: "Example Corp", w3cid: 11111 },
],
formerEditors: [
{ name: "Bob Jones", company: "Old Corp", w3cid: 22222 },
{ name: "Carol White", retiredDate: "2022-06-30", w3cid: 33333 },
],
};
formerEditors to keep a clean current editors list while acknowledging past contributorsretiredDate to a person in editors to show them inline as "until [date]"github📝 EditType: string | GithubOptions
Default: undefined
Associates the specification with a GitHub repository. Adds a "Feedback:" section to the document header with links to file issues, view open issues, and see pull requests. Also auto-sets edDraftURI and issueBase.
var respecConfig = {
github: "w3c/payment-request",
};
var respecConfig = {
github: "https://github.com/w3c/payment-request",
};
var respecConfig = {
github: {
repoURL: "https://github.com/w3c/payment-request",
branch: "main",
},
};
var respecConfig = {
github: {
repoURL: "https://github.com/w3c/aria",
pullsURL: "https://github.com/w3c/aria/pulls?q=is%3Apr+is%3Aopen+label%3Acore-aam",
commitHistoryURL: "https://github.com/w3c/aria/commits/main/core-aam/",
},
};
| Option | Type | Default | Description |
|---|---|---|---|
repoURL |
string |
— | Full URL to the GitHub repository |
branch |
string |
"gh-pages" |
Branch used for GitHub Pages |
pullsURL |
string |
auto | Filtered pull requests URL (useful for monorepos) |
commitHistoryURL |
string |
auto | Filtered commits URL (useful for monorepos) |
github auto-populates edDraftURI — no need to set it separatelypullsURL and commitHistoryURL to filter to your spec's fileshighlightVars📝 EditType: boolean
Default: true
Enables click-to-highlight for <var> elements in algorithms. When a reader clicks a variable, all instances of that variable within the same section are highlighted, making it easier to trace variable usage through long algorithms.
var respecConfig = {
highlightVars: false,
};
<var> elements: Let <var>request</var> be a new request..algorithm list or <section> — whichever is closest|variable| shorthand automatically generates <var> elementsisPreview📝 EditType: boolean
Default: false
Adds a prominent red warning banner to the document indicating that this is a preview and should not be cited or referenced. Used for preview deployments (e.g. from pull request previews) to distinguish them from official versions.
var respecConfig = {
isPreview: true,
};
license📝 EditType: string
Default: "w3c-software-doc"
The copyright license for the document.
var respecConfig = {
// w3c-software-doc is already the default for W3C documents
};
var respecConfig = {
license: "cc0",
};
| Value | License | Notes |
|---|---|---|
"w3c-software-doc" |
W3C Software and Document License | Default for W3C documents. Recommended. |
"w3c-software" |
W3C Software License | Permissive, GPL-compatible, attribution required. |
"cc0" |
CC0 | Maximally permissive. Recommended for WHATWG documents. Not supported for W3C. |
"cc-by" |
CC-BY | Experimentally available in some groups. Uses dual licensing. |
"document" |
W3C Document License | ⚠️ Not recommended. Use "w3c-software-doc" instead. |
"dual" |
W3C Dual License | ⚠️ Not recommended. Use "w3c-software-doc" instead. |
license explicitlycc0 is intended for documents heading to the WHATWG; W3C does not support itlint📝 EditType: boolean | LintRules
Default: true
Controls ReSpec's built-in linter. When enabled, the linter checks the document for common mistakes and best practice violations, showing warnings in the document header.
var respecConfig = {
// lint: true is the default — no need to set it explicitly
};
var respecConfig = {
lint: false,
};
var respecConfig = {
lint: {
"no-http-props": false, // disable (was on by default)
"no-unused-dfns": true, // enable (was off by default)
"check-punctuation": "warn", // warn instead of error
},
};
| Rule | Default | What it checks |
|---|---|---|
a11y |
false |
Accessibility issues |
check-charset |
false |
Missing or duplicate <meta charset="utf-8"> |
check-internal-slots |
false |
Internal slot references missing the . separator (|obj|.[[slot]]) |
check-punctuation |
false |
Missing punctuation at end of paragraphs |
informative-dfn |
false |
Definitions in informative sections |
local-refs-exist |
true |
Local #fragment links that don't resolve |
no-captionless-tables |
true |
Tables without a <caption> |
no-dfn-in-abstract |
false |
<dfn> elements in abstract, SotD, or other unnumbered sections |
no-headingless-sections |
true |
Sections without a heading |
no-http-props |
true |
Non-HTTPS URLs in config |
no-unused-dfns |
false |
Defined terms never referenced |
no-unused-vars |
false |
WebIDL variables never used |
privsec-section |
false |
Missing Privacy and Security Considerations section |
wpt-tests-exist |
false |
data-tests attributes pointing to non-existent WPT tests |
Use data-lint-ignore to suppress a specific warning on an element:
<table data-lint-ignore="no-captionless-tables">
<tr><td>data</td></tr>
</table>
true (error), "warn" (warning), or false (disabled)a11y linting rule📝 EditDefault: false
Runs accessibility checks using axe-core. Reports violations as ReSpec warnings, highlighting the offending elements in the document.
var respecConfig = {
lint: {
a11y: true,
},
};
var respecConfig = {
lint: {
a11y: {
runOnly: ["image-alt", "link-name"],
},
},
};
var respecConfig = {
lint: {
a11y: {
rules: {
"color-contrast": { enabled: true }, // slow — disabled by default
"image-alt": { enabled: false },
},
},
},
};
These axe-core rules run if you enable a11y: true, except the following, which are disabled because they are slow or produce false positives on spec documents:
| Rule | Reason disabled |
|---|---|
color-contrast |
Too slow — enable explicitly when needed |
landmark-one-main |
Spec pages often lack <main>; would mark entire page as errored |
landmark-unique |
Causes false positives in spec document structure |
region |
Similar false-positive issue with spec layout |
All other axe-core default rules run. For the full list, see axe-core rule descriptions.
Add ?a11y=true to any spec URL to enable all default rules temporarily, without changing config.
var respecConfig = {
lint: { a11y: false },
};
check-punctuation linting rule📝 EditDefault: false
Warns when a <p> element does not end with punctuation. Helps maintain consistent typographic quality in specifications.
<!-- BAD: paragraph ends without punctuation -->
<p>The widget is initialized during construction</p>
Add a period (or other appropriate punctuation) at the end of the paragraph.
var respecConfig = {
lint: {
"check-punctuation": true,
},
};
var respecConfig = {
lint: { "check-punctuation": false },
};
informative-dfn linting rule📝 EditDefault: false
Warns when a link in a normative section points to a definition that was defined in an informative section. Normative text should not depend on informatively-defined terms.
<section class="informative">
<dfn>fancy algorithm</dfn> is described here.
</section>
<section>
<h2>Processing Model</h2>
<!-- BAD: normative section linking to informative definition -->
<p>Run the <a>fancy algorithm</a>.</p>
</section>
Either:
<dfn> to a normative section<dfn data-cite="spec#fancy-algorithm">fancy algorithm</dfn>class="lint-ignore" to the specific link to suppress the warningvar respecConfig = {
lint: { "informative-dfn": true },
};
local-refs-exist linting rule📝 EditDefault: true
Warns when an href="#fragment" link points to an anchor that doesn't exist in the document.
<section id="foo">...</section>
<!-- BAD: #bar doesn't exist in the document -->
<a href="#bar">link</a>
Either fix the href to point to an existing ID, or add the missing ID to the target element.
var respecConfig = {
lint: { "local-refs-exist": false },
};
no-captionless-tables linting rule📝 EditDefault: true
Warns when a numbered <table> (with class="numbered") does not have a <caption> as its first child.
<!-- BAD: numbered table without a caption -->
<table class="numbered">
<tr><th>Feature</th><th>Status</th></tr>
<tr><td>Thing</td><td>Done</td></tr>
</table>
<table class="numbered">
<caption>Feature implementation status</caption>
<tr><th>Feature</th><th>Status</th></tr>
<tr><td>Thing</td><td>Done</td></tr>
</table>
var respecConfig = {
lint: { "no-captionless-tables": false },
};
<table class="numbered"> — unnumbered tables are not checked<caption> must be the first child of <table>no-headingless-sections linting rule📝 EditDefault: true
Warns when a <section> element does not begin with a heading element (<h2>–<h6>).
<!-- BAD: no heading -->
<section id="intro">
<p>Content without a heading.</p>
</section>
<section id="intro">
<h2>Introduction</h2>
<p>Content with a heading.</p>
</section>
var respecConfig = {
lint: { "no-headingless-sections": false },
};
<body> element itself, which is not required to start with a headingno-http-props linting rule📝 EditDefault: true
Warns when any URL in respecConfig uses http:// instead of https://. W3C publication rules require HTTPS.
var respecConfig = {
// BAD: http:// not https://
implementationReportURI: "http://example.org/report.html",
};
Change http:// to https:// for the flagged URL.
var respecConfig = {
lint: { "no-http-props": false },
};
no-unused-dfns linting rule📝 EditDefault: false
Warns when a definition (<dfn>) is never referenced anywhere in the document and is not exported.
var respecConfig = {
lint: {
"no-unused-dfns": true,
},
};
<!-- Defined but never linked to anywhere in the document: -->
<dfn>orphaned concept</dfn>
Choose one:
[=orphaned concept=]<dfn class="export">orphaned concept</dfn><dfn> if the term is no longer needed<span class="dfn-paneled">term</span>var respecConfig = {
lint: { "no-unused-dfns": false },
};
no-unused-vars linting rule📝 EditDefault: false
Warns when a <var> element in an algorithm is defined (first occurrence) but never referenced again. Only checks variables inside <ol class="algorithm"> sections.
<ol class="algorithm">
<li>Let |request| be a new request.</li>
<li>Let |unused| be null.</li> <!-- warned: never used again -->
<li>Set |request|'s URL to the URL.</li>
</ol>
var respecConfig = {
lint: { "no-unused-vars": true },
};
<var data-ignore-unused>someVar</var>
<ol class="algorithm"> sections|variable| is treated as its definition|variable| shorthand does not support data-ignore-unused — use <var data-ignore-unused> explicitlyprivsec-section linting rule📝 EditDefault: false (but on by default for W3C specs via respecConfig.lint)
Warns when the document is missing a Privacy and/or Security Considerations section. Required for W3C specifications that contain normative content.
<section>
<h2>Privacy and Security Considerations</h2>
<p>This specification introduces no new privacy or security concerns
beyond those described in [[FETCH]].</p>
</section>
var respecConfig = {
lint: { "privsec-section": true },
};
var respecConfig = {
lint: { "privsec-section": false },
};
<h2> titled "Privacy and Security Considerations" or similarwpt-tests-exist linting rule📝 EditDefault: false
Warns when a data-tests attribute references a WPT test file that doesn't exist in the web-platform-tests repository.
var respecConfig = {
testSuiteURI: "https://github.com/web-platform-tests/wpt/tree/HEAD/payment-request/",
lint: {
"wpt-tests-exist": true,
},
};
<!-- BAD: nonexistent-test.html doesn't exist in WPT -->
<p data-tests="valid-test.html,nonexistent-test.html"></p>
Either correct the test path or remove the reference to the non-existent test.
testSuiteURI to be set — ReSpec uses it to determine the WPT base pathdata-tests for how to annotate spec sections with test referenceslocalBiblio📝 EditType: Object
Default: {}
Adds custom bibliography entries that are not in the SpecRef database, or overrides existing entries for this document.
var respecConfig = {
localBiblio: {
"MY-SPEC": {
title: "My Custom Specification",
href: "https://example.org/my-spec/",
status: "ED",
publisher: "Example Community Group",
},
},
};
Then cite it in the document as [[MY-SPEC]] (informative) or [[!MY-SPEC]] (normative).
| Field | Type | Description |
|---|---|---|
title |
string |
Required. The title of the referenced document |
href |
string |
URL of the document |
status |
string |
Publication status (e.g. "ED", "WD", "REC") |
publisher |
string |
Publishing organization |
authors |
string[] |
List of author names |
date |
string |
Publication date |
id |
string |
Identifier (if different from the key) |
aliasOf |
string |
Makes this entry an alias of another reference key |
localBiblio should be a last resort. Entries in SpecRef benefit all specs, not just yours.[[fetch]] and [[FETCH]] refer to the same entry)logos📝 EditType: Logo[]
Default: [W3C logo]
Overrides the standard W3C logo(s) in the document header. Useful for Community Groups, joint deliverables, or documents with custom branding.
var respecConfig = {
logos: [
{
src: "https://example.org/logo.svg",
alt: "Example Community Group",
url: "https://example.org/",
height: 48,
},
],
};
var respecConfig = {
logos: [
{
src: "https://www.w3.org/StyleSheets/TR/2021/logos/W3C",
alt: "W3C",
url: "https://www.w3.org/",
height: 48,
},
{
src: "https://partner.example/logo.svg",
alt: "Partner Org",
url: "https://partner.example/",
height: 48,
},
],
};
| Field | Type | Required | Description |
|---|---|---|---|
src |
string |
Yes | URL of the logo image |
alt |
string |
Yes | Alt text for the image |
url |
string |
No | Link URL when the logo is clicked |
height |
number |
No | Image height in pixels |
width |
number |
No | Image width in pixels |
id |
string |
No | id attribute on the logo element |
logos replaces the default W3C logo — include the W3C logo explicitly if you need it alongside your custom logomaxTocLevel📝 EditType: number
Default: 0 (all levels)
Limits the depth of the table of contents. 0 means unlimited. Set to 2 to show only top-level sections and their direct children, 3 for one more level, etc.
var respecConfig = {
maxTocLevel: 2,
};
maxTocLevel: 0 (default) includes all heading levels in the ToCdata-max-toc="N" on individual sections to override for that subtreemdn📝 EditType: boolean | string | MdnOptions
Default: undefined
Adds MDN browser compatibility annotations to relevant sections of the specification. Annotations are shown as expandable panels in the right margin, sourced from MDN's browser-compat-data via the mdn-spec-links project.
var respecConfig = {
shortName: "payment-request",
mdn: true,
};
var respecConfig = {
mdn: "payment-request",
};
var respecConfig = {
mdn: {
key: "payment-request",
maxAge: 3600000, // 1 hour cache
},
};
| Option | Type | Default | Description |
|---|---|---|---|
key |
string |
shortName |
Key used to look up MDN data. Browse keys at SPECMAP.json. |
baseJsonPath |
string |
https://w3c.github.io/mdn-spec-links/ |
Custom base URL for MDN spec links data |
maxAge |
number |
86400000 |
Cache duration in milliseconds (default: 24 hours) |
modificationDate📝 EditType: string
Default: undefined
The date of an in-place editorial edit to an already-published document, in "YYYY-MM-DD" format. Used alongside publishDate for errata corrections and editorial fixes that do not require a new publication date per W3C Pubrules.
var respecConfig = {
publishDate: "2020-03-30",
modificationDate: "2020-04-13",
};
"YYYY-MM-DD"publishDate insteadmonetization📝 EditType: boolean | string | MonetizationOptions
Default: ReSpec's payment pointer
Adds a Web Monetization <meta> payment pointer tag to the document. By default uses ReSpec's own payment pointer. Stripped from saved HTML unless removeOnSave: false is set.
var respecConfig = {
monetization: "$wallet.example.com/my-wallet",
};
var respecConfig = {
monetization: false,
};
var respecConfig = {
monetization: {
paymentPointer: "$wallet.example.com/my-wallet",
removeOnSave: false,
},
};
| Option | Type | Default | Description |
|---|---|---|---|
paymentPointer |
string |
ReSpec's pointer | The payment pointer URL |
removeOnSave |
boolean |
true |
Strip the meta tag when saving to static HTML |
false disables monetization and removes the default ReSpec pointernoTOC📝 EditType: boolean
Default: false
Suppresses generation of the table of contents.
var respecConfig = {
noTOC: true,
};
class="notoc" to the section — see notoc-classotherLinks📝 EditType: OtherLink[]
Default: []
Adds custom link sections to the document header. Use this to link to implementation trackers, test suites, issue trackers in other repos, or any other relevant resources.
var respecConfig = {
otherLinks: [
{
key: "Implementation status",
data: [
{
value: "Chrome",
href: "https://chromestatus.com/feature/12345",
},
{
value: "Firefox",
href: "https://bugzilla.mozilla.org/show_bug.cgi?id=12345",
},
{
value: "Safari",
href: "https://bugs.webkit.org/show_bug.cgi?id=12345",
},
],
},
],
};
Each entry in otherLinks is an object:
| Field | Type | Description |
|---|---|---|
key |
string |
Section heading shown in the header |
data |
LinkData[] |
Array of link items |
Each item in data:
| Field | Type | Description |
|---|---|---|
value |
string |
Link text (or plain text if no href) |
href |
string |
URL. Omit to display value as plain text. |
otherLinks entries each get their own section headingpluralize📝 EditType: boolean
Default: true (W3C profile)
Enables automatic pluralization for <dfn> elements. When enabled, a term defined as <dfn>widget</dfn> can also be referenced as <a>widgets</a> without needing a data-lt attribute.
var respecConfig = {
// pluralize: true is already the default for W3C specs
};
<dfn>user agent</dfn>
<!-- Both of these link correctly: -->
<a>user agent</a>
<a>user agents</a>
<dfn data-lt="pub">bar</dfn>
<!-- All of these link correctly: -->
<a>bar</a> <a>bars</a> <a>pub</a>
<dfn data-lt-no-plural>CSS</dfn>
<!-- "CSSs" will NOT be recognized as a link -->
data-lt-no-plural to suppress pluralization for acronyms, brand names, or terms where pluralization would be wrongdata-lt for manually defining alternative formspostProcess📝 EditType: Array<(config: Object, document: Document, utils: Object) => void | Promise<void>>
Default: []
An array of functions that run after ReSpec has finished all processing. Use this to add custom sections, validate the final output, or modify generated markup.
async function addImplStatus(config, document) {
const res = await fetch("https://api.example.org/impl-status.json");
const status = await res.json();
// Add a badge to each section that has implementation data
for (const [id, data] of Object.entries(status)) {
const section = document.getElementById(id);
if (!section) continue;
const badge = document.createElement("span");
badge.className = "impl-badge";
badge.textContent = `${data.implementations} implementations`;
section.querySelector("h2, h3")?.append(" ", badge);
}
}
var respecConfig = {
postProcess: [addImplStatus],
};
function validateSpec(config, document) {
// Check that all normative sections have at least one dfn or algorithm
const normativeSections = document.querySelectorAll(
"section:not(.informative):not(.appendix)"
);
for (const section of normativeSections) {
if (!section.querySelector("dfn, ol.algorithm")) {
console.warn("Section with no dfn or algorithm:", section.id);
}
}
}
var respecConfig = {
postProcess: [validateSpec],
};
Each function receives three arguments:
| Argument | Type | Description |
|---|---|---|
config |
Object |
The respecConfig object plus ReSpec internal state |
document |
Document |
The fully processed ReSpec document |
utils |
Object |
ReSpec utility functions |
document.respec.readypreProcesspreProcess📝 EditType: Array<(config: Object, document: Document, utils: Object) => void | Promise<void>>
Default: []
An array of functions that run before ReSpec begins processing. Use this to fetch external data, inject content into the document, or perform setup that other processing steps depend on.
async function loadTerms(config, document) {
const res = await fetch("https://api.example.org/terms.json");
const terms = await res.json();
// Inject <dfn> elements so xref can resolve them
const section = document.querySelector("#terminology");
for (const { id, label } of terms) {
const p = document.createElement("p");
p.innerHTML = `The <dfn data-export id="${id}">${label}</dfn> is ...`;
section.append(p);
}
}
var respecConfig = {
preProcess: [loadTerms],
};
function addGeneratedSection(config, document) {
const section = document.createElement("section");
section.id = "build-info";
section.innerHTML = `
<h2>Build Information</h2>
<p>Built by: <strong>${config.editors[0].name}</strong></p>
`;
document.body.insertAdjacentElement("beforeend", section);
}
var respecConfig = {
preProcess: [addGeneratedSection],
};
Each function receives three arguments:
| Argument | Type | Description |
|---|---|---|
config |
Object |
The respecConfig object plus ReSpec internal state |
document |
Document |
The HTML document in its original, unprocessed form |
utils |
Object |
ReSpec utility functions |
async functions are fully supportedpreProcess runs before any ReSpec transformation — the document is still in its original source form. Definitions, headings, and xrefs have not yet been processed.postProcesspublishDate📝 EditType: string
Default: document's last-modified date
The publication date of this version of the document, in "YYYY-MM-DD" format. For Editor's Drafts and unofficial documents, leave this unset — ReSpec uses the document's last-modified date automatically. For documents being published to W3C TR/, set this explicitly.
var respecConfig = {
publishDate: "2025-06-15",
};
"YYYY-MM-DD""ED" status, omit this — ReSpec uses the browser's last-modified date, which is always current"WD", "CR", "REC", etc.), set this to the actual publication date"ED" specs, set publishDate explicitlyshortName📝 EditType: string
Default: undefined
The specification's short name — used in W3C TR/ URLs (e.g. https://www.w3.org/TR/short-name/) and several other generated URLs.
var respecConfig = {
shortName: "payment-request",
};
edDraftURI is not set), and the mdn annotation key (when mdn is true)"fetch", "web-animations", "css-color-5")specStatus📝 EditType: string
Default: "ED"
The publication status of the document. Controls the document title, status boilerplate, and which sections are shown.
var respecConfig = {
specStatus: "ED",
};
var respecConfig = {
specStatus: "WD",
previousPublishDate: "2024-01-15",
previousMaturity: "FPWD",
};
| Value | Full name | Required with |
|---|---|---|
"ED" |
Editor's Draft | — |
"FPWD" |
First Public Working Draft | — |
"WD" |
Working Draft | previousPublishDate, previousMaturity |
"CR" |
Candidate Recommendation Snapshot | crEnd, implementationReportURI |
"CRD" |
Candidate Recommendation Draft | crEnd |
"PR" |
Proposed Recommendation | crEnd, prEnd |
"REC" |
Recommendation | — |
"RSCND" |
Rescinded Recommendation | — |
"DISC" |
Discontinued Draft | — |
| Value | Full name |
|---|---|
"DNOTE" |
Group Note Draft |
"NOTE" |
Group Note |
"STMT" |
Statement |
| Value | Full name |
|---|---|
"DRY" |
Registry Draft |
"CRYD" |
Candidate Registry Draft |
"CRY" |
Candidate Registry Snapshot |
"RY" |
Registry |
| Value | Full name |
|---|---|
"CG-DRAFT" |
Draft Community Group Report |
"CG-FINAL" |
Final Community Group Report |
"BG-DRAFT" |
Draft Business Group Report |
"BG-FINAL" |
Final Business Group Report |
| Value | Full name | Notes |
|---|---|---|
"unofficial" or "UD" |
Unofficial Draft | For personal or exploratory drafts. Licensed CC-BY v3.0 by default. |
"base" |
(no status) | Minimal output — no W3C boilerplate. Useful for plain documentation. |
"LS" |
Living Standard | For continuously-updated living standards. |
"LD" |
Living Document | Similar to Living Standard. |
"Member-SUBM" |
Member Submission | Requires submissionCommentNumber. |
"MO" |
Member-Only Document | For W3C member-restricted documents. |
"finding" |
TAG Finding | For published TAG findings. |
"draft-finding" |
Draft TAG Finding | |
"editor-draft-finding" |
Draft TAG Finding (GitHub) | For TAG documents maintained on GitHub. |
"ED" is the default — it does not appear on W3C TR/; safe for active developmentnoRecTrack if the document should not follow the Recommendation track"unofficial", content is auto-licensed under CC-BY v3.0; use license to change thissubjectPrefix📝 EditType: string
Default: undefined
Adds a prefix to mailing list feedback subjects. When set, feedback links in the document header will include this prefix in the mailto: subject line.
var respecConfig = {
subjectPrefix: "[payment-request]",
};
"[my-spec]" not "my-spec")wgPublicList or similar)github configured, GitHub issues are the preferred feedback channelsubtitle📝 EditType: string
Default: ""
A subtitle shown below the document title in the header.
var respecConfig = {
subtitle: "Level 1",
};
level which integrates with shortName and ToC numberingtestSuiteURI📝 EditType: string
Default: undefined
URL of the test suite for this specification. Shown in the document header as a "Test suite" link.
var respecConfig = {
testSuiteURI: "https://wpt.fyi/payment-request/",
};
wpt-tests-exist linting rule — ReSpec uses this URL to validate data-tests pathshttps://wpt.fyi/...), GitHub URL, or any test suite URLhttps://github.com/web-platform-tests/wpt/tree/HEAD/your-spec/ for the WPT GitHub tree viewxref📝 EditType: boolean | string | string[] | XrefOptions
Default: true (W3C profile)
Enables automatic cross-reference linking. When a term is wrapped in [= =] or {{ }} shorthand syntax, ReSpec automatically links it to the defining specification.
var respecConfig = {
xref: "web-platform",
};
Then write terms naturally — ReSpec links them automatically:
<p>
[=Queue a task=] to [=fire an event=] named "fetch"
at the {{Window}} object.
</p>
Understanding the pipeline helps when terms aren't found:
Your spec writes [=fetch=]
↓
ReSpec queries the xref service (respec.org/xref)
↓
Service looks up "fetch" in the WebRef database
↓
WebRef is populated by Reffy, which crawls published specs every 6 hours
↓
Reffy finds terms marked with <dfn data-export> in published specs
↓
Term found → generates <a href="https://fetch.spec.whatwg.org/#concept-fetch">fetch</a>
Term not found → ReSpec shows a red error banner
For a term to be findable via xref, ALL of these must be true:
<dfn> in the defining spec has data-export or class="export"If a term isn't in the database, ask the defining spec's editors to add data-export. See data-export.
var respecConfig = {
xref: true,
};
var respecConfig = {
xref: "web-platform",
};
The "web-platform" profile includes: HTML, INFRA, URL, WEBIDL, DOM, FETCH.
var respecConfig = {
xref: ["FETCH", "DOM"],
};
var respecConfig = {
xref: {
profile: "web-platform",
specs: ["PERMISSIONS", "SCREEN-WAKE-LOCK"],
},
};
| Option | Type | Description |
|---|---|---|
profile |
string |
Pre-defined profile name (e.g. "web-platform") |
specs |
string[] |
Additional spec shortnames to include in lookups |
url |
string |
Custom xref API URL (advanced — not normally needed) |
profile and specs are set, both sets of specs are used for disambiguationdata-citeadditionalCopyrightHolders📝 EditType: string
Default: undefined
Adds an additional copyright holder alongside W3C in the document copyright notice. Used when publishing documents developed in cooperation with other standards organizations (e.g., IETF) or when the spec is jointly owned.
var respecConfig = {
additionalCopyrightHolders: "Internet Engineering Task Force",
};
"unofficial" documents: replaces the default CC license text entirelyalternateFormats📝 EditType: Array<{ label: string, uri: string }>
Default: []
Shows links to alternate formats of the specification (PDF, ePub, etc.) in the document header.
var respecConfig = {
alternateFormats: [
{
label: "PDF",
uri: "https://www.w3.org/TR/my-spec/my-spec.pdf",
},
{
label: "ePub",
uri: "https://www.w3.org/TR/my-spec/my-spec.epub",
},
],
};
label (display text) and uri (URL)canonicalURI📝 EditType: string | "edDraft" | "TR"
Default: undefined
Sets the <link rel="canonical"> URL for the document, helping search engines identify the authoritative version.
var respecConfig = {
shortName: "payment-request",
canonicalURI: "TR",
};
var respecConfig = {
canonicalURI: "edDraft",
};
var respecConfig = {
canonicalURI: "https://respec.org/docs/",
};
| Value | Generates |
|---|---|
"TR" |
https://www.w3.org/TR/shortName/ |
"edDraft" |
The value of edDraftURI |
"TR" for the published version to ensure search engines index the stable W3C TR/ URL rather than the Editor's DraftcharterDisclosureURI📝 EditType: string
Default: undefined
URL to the patent disclosure section of the group charter. Required for Interest Group Notes — points to the W3C publication rules requirement for patent policy disclosure.
var respecConfig = {
charterDisclosureURI: "https://www.w3.org/2019/06/me-ig-charter.html#patentpolicy",
};
copyrightStart📝 EditType: number
Default: year of publishDate
The first year of the copyright period. When a spec has been developed over multiple years, use this to show a copyright range (e.g., "Copyright © 2018–2025").
var respecConfig = {
copyrightStart: 2018,
publishDate: "2025-06-01",
// Results in: "Copyright © 2018-2025 W3C®"
};
copyrightStart equals the publishDate year, it has no effect (year range is suppressed)crEnd📝 EditType: string
Default: undefined
The end date of the Candidate Recommendation review period, in "YYYY-MM-DD" format. Required when specStatus is "CR" or "CRD". This date tells implementers how long they have before the spec may advance to Proposed Recommendation.
var respecConfig = {
specStatus: "CR",
crEnd: "2025-09-01",
};
"CR" and "CRD" — ReSpec will warn if missing"PR" (alongside prEnd)"YYYY-MM-DD"doJsonLd📝 EditType: boolean
Default: false
Adds a <script type="application/ld+json"> element with schema.org metadata describing the document. Useful for search engine discoverability.
var respecConfig = {
doJsonLd: true,
canonicalURI: "TR",
license: "w3c-software-doc",
};
canonicalURI and license to be set for the JSON-LD to be completeTechArticle schema.org typeerrata📝 EditType: string
Default: undefined
URL to the errata document for this specification. Shown in the document header. Typically only relevant for "REC" (Recommendation) documents.
var respecConfig = {
specStatus: "REC",
errata: "https://www.w3.org/XML/xml-V10-5e-errata",
};
"REC" documents that have accumulated corrections since publicationgroup📝 EditType: string | string[]
Default: undefined
Associates the specification with a W3C working group (or other group type). ReSpec uses this to automatically configure patent policy boilerplate, group links, and the status section.
This replaces the old wg, wgId, wgURI, wgPatentURI, and wgPublicList options.
var respecConfig = {
group: "webapps",
};
var respecConfig = {
group: ["webapps", "css"],
};
var respecConfig = {
group: "wg/wot", // "wg/", "cg/", "ig/", or "bg/" prefix
};
specStatus values per group type📝 EditThe group type determines which specStatus values are valid. Using the wrong combination produces an error.
| Group type | Examples | Valid specStatus values |
|---|---|---|
Working Group (wg/) |
"webapps", "css" |
"ED", "FPWD", "WD", "CR", "CRD", "PR", "REC", "NOTE", "DNOTE", … |
Community Group (cg/) |
"wicg", "webassembly" |
"CG-DRAFT", "CG-FINAL" |
Business Group (bg/) |
"BG-DRAFT", "BG-FINAL" |
|
Interest Group (ig/) |
"NOTE", "DNOTE" |
var respecConfig = {
group: "wicg",
specStatus: "CG-DRAFT", // NOT "ED" — that's for Working Groups
};
group option auto-populates patent policy, group homepage link, mailing list, and participant counttype/shortname form (e.g. "wg/csv") and refer to w3.org/groups/ to find the correct values"cg/wot" vs "wg/wot"wg, wgId, wgURI, wgPatentURI, wgPublicList — do not use those deprecated options alongside groupimplementationReportURI📝 EditType: string
Default: undefined
URL of the implementation report showing how implementations perform against the test suite. Shown in the document header as an "Implementation report" link. Required for Candidate Recommendation ("CR") documents.
var respecConfig = {
specStatus: "CR",
implementationReportURI: "https://wpt.fyi/results/payment-request",
};
"CR" — reviewers need to see implementation statuslatestVersion📝 EditType: string
Default: auto-generated from shortName
The URL of the latest version of this specification. For W3C Working Groups, this is auto-generated as https://www.w3.org/TR/shortName/. Set this explicitly for Community Groups, Business Groups, or to override the default.
var respecConfig = {
latestVersion: "https://wicg.github.io/my-feature/",
};
null to suppress the "Latest Published Version" link entirelylevel📝 EditType: number
Default: undefined
Sets the "level" of a leveled specification. Appends "Level N" to the document title and adds the level number to shortName. Used by CSS Working Group and other groups that publish progressive levels of a spec.
var respecConfig = {
level: 5,
shortName: "css-color",
// Title becomes: "CSS Color Level 5"
// shortName becomes: "css-color-5"
};
shortName (e.g. css-color-5)noRecTrack📝 EditType: boolean
Default: false
Marks the document as not intended to become a W3C Recommendation. Use this for Group Notes, informational documents, and Working Group Notes that are on the Notes track rather than the Recommendation track.
var respecConfig = {
specStatus: "NOTE",
noRecTrack: true,
};
specStatus is a Notes-track value ("DNOTE", "NOTE", "STMT") to make this explicitspecStatus is set alongside noRecTrack: trueprEnd📝 EditType: string
Default: undefined
The end date of the Proposed Recommendation review period, in "YYYY-MM-DD" format. Required when specStatus is "PR".
var respecConfig = {
specStatus: "PR",
crEnd: "2025-06-01",
prEnd: "2025-08-01",
};
"PR" — ReSpec will warn if missing"PR" also requires crEnd"YYYY-MM-DD"prevED📝 EditType: string
Default: undefined
URL of a previous Editor's Draft location. Used when a document has moved, been transferred between groups, or split from a larger document — situations where the version control history is no longer directly accessible.
var respecConfig = {
prevED: "https://old-location.example.org/my-spec/",
};
previousDiffURI📝 EditType: string
Default: undefined
The URL to use as the "old" version when generating a diff-marked document. By default, ReSpec uses the previous published version. Override this to diff against a different version.
var respecConfig = {
previousPublishDate: "2024-01-15",
previousMaturity: "WD",
// Override: diff against the very first WD, not the immediately previous one
previousDiffURI: "https://www.w3.org/TR/2021/WD-my-spec-20210301/",
};
previousMaturity📝 EditType: string
Default: undefined
The specStatus value of the previous version of this document. Required when previousPublishDate is set — ReSpec uses it to construct the "Previous Version" URL.
var respecConfig = {
specStatus: "WD",
publishDate: "2025-06-15",
previousPublishDate: "2024-12-01",
previousMaturity: "WD",
};
previousPublishDatespecStatus identifier (e.g. "WD", "CR", "FPWD")"FPWD" (first publication), omit both fieldspreviousPublishDate📝 EditType: string
Default: undefined
The "YYYY-MM-DD" publication date of the previous version of this document. Used to generate the "Previous Version" link in the document header. Required for most Recommendation Track documents ("WD", "CR", "PR", "REC").
var respecConfig = {
specStatus: "WD",
publishDate: "2025-06-15",
previousPublishDate: "2024-12-01",
previousMaturity: "WD",
};
previousMaturity"FPWD" (first publication), omit both — there is no previous version"YYYY-MM-DD"prevRecShortname📝 EditType: string
Default: undefined
The shortName of a previous version of this document that is a W3C Recommendation. Used when publishing a new version (e.g., Level 2) of an existing Recommendation.
var respecConfig = {
shortName: "css-grid-2",
prevRecShortname: "css-grid-1",
};
shortNameprevRecURI to specify the full URL instead of the shortNameprevRecURI📝 EditType: string
Default: auto-generated from prevRecShortname
The URL of the previous W3C Recommendation this document supersedes. Use a dated URL for stability.
var respecConfig = {
prevRecURI: "https://www.w3.org/TR/2014/REC-css-color-3-20140805/",
};
/TR/shortname/ shortcut — if the Recommendation is later rescinded, the undated link may become stale or redirectprevRecShortname is set, ReSpec auto-generates https://www.w3.org/TR/prevRecShortname/submissionCommentNumber📝 EditType: string
Default: undefined
The W3C Team comment number for a Member Submission. Required when specStatus is "Member-SUBM".
var respecConfig = {
specStatus: "Member-SUBM",
submissionCommentNumber: "03",
};
https://www.w3.org/Submission/[year]/[number]/Comment/ in the headerwgPublicList📝 Edit⚠️ Deprecated. Use group instead.
Previously used to set the short name of the group's public mailing list. The group option auto-configures this.
// Before:
// wgPublicList: "public-webapps",
// After:
var respecConfig = {
group: "webapps",
};
<section id="conformance">📝 EditA <section> with id="conformance" tells ReSpec to insert the standard RFC 2119 conformance boilerplate. Add any spec-specific conformance text after the placeholder — ReSpec will prepend the boilerplate above it.
If your spec uses RFC 2119 keywords (MUST, SHOULD, MAY, etc.), you need this section. ReSpec will warn you if RFC 2119 keywords are present but the conformance section is missing:
<div class="advisement">
Warning: Document uses RFC2119 keywords but lacks a conformance section.</div>
Hint: Please add a <section id="conformance">.
<section id="conformance">
<p>This specification defines conformance criteria that apply
to a single product: the <em>widget</em>.</p>
</section>
Add class="override" to take full control and write your own conformance text without any generated boilerplate:
<section id="conformance" class="override">
<h2>Conformance</h2>
<p>This document defines requirements for implementations. An implementation
is conformant if it satisfies all the normative requirements herein.</p>
</section>
class="override" skips all generated content — the section is left exactly as authoredgh-contributors📝 EditAutomatically populates an element with a list of GitHub contributors to the repository. Requires github to be configured.
Add an element with id="gh-contributors" anywhere in the document — ReSpec replaces its content with a list of contributors linked to their GitHub profiles.
<section>
<h2>Contributors</h2>
<p>We thank the following contributors:</p>
<ul id="gh-contributors"></ul>
</section>
<p>
Also thanks to: <span id="gh-contributors"></span>.
</p>
github to be configured in respecConfig<section id="idl-index">📝 EditGenerates a consolidated WebIDL index — all the WebIDL definitions in the spec gathered into one place, formatted as a single block.
<section id="idl-index" class="appendix">
<!-- All WebIDL from across the document appears here -->
</section>
<section id="idl-index" class="appendix">
<h2>Complete API Definition</h2>
<p>The following shows the complete WebIDL for this specification.</p>
<!-- WebIDL is inserted after the custom content -->
</section>
Add class="exclude" to any <pre class="idl"> to keep it out of the IDL index — useful for non-normative illustrative examples:
<pre class="idl exclude">
// This example IDL is not normative
interface Example {};
</pre>
IDL blocks inside non-normative sections (class="informative") are automatically excluded.
<pre class="idl"> block in the document and combines themclass="exclude" or inside informative sections are skipped<section id="index">📝 EditGenerates a comprehensive terms index — all terms defined in this spec and all terms referenced from other specs, in a single searchable section.
<section id="index" class="appendix">
<!-- ReSpec generates the index here -->
</section>
<section id="index" class="appendix">
<h2>Index of All Terms</h2>
<p>Defined terms and external references used in this specification.</p>
<!-- Index generated after custom content -->
</section>
<section id="index" class="appendix prefer-full-spec-title">
<!-- Shows "DOM Standard" instead of "[DOM]" -->
</section>
<dfn>) and externally referenced terms (via xref)class="prefer-full-spec-title" shows full spec titles (e.g., "DOM Standard") instead of shortnames (e.g., "[DOM]")<section id="issue-summary">📝 EditGenerates a consolidated list of all issue boxes referenced throughout the document.
<div class="issue" data-number="42">
<p>We need to decide the algorithm.</p>
</div>
<!-- Later in the document: -->
<section id="issue-summary" class="appendix">
<!-- All issue boxes are listed here automatically -->
</section>
class="issue" across the documentdata-number is set), the title (if title attribute is set), and a link back to the issue in the document<section id="references">📝 EditAdding a <section id="references"> lets you add custom content to the references section. ReSpec appends the auto-generated normative and informative references after any custom content.
<section id="references">
<p>Unless otherwise specified, all references are to the
latest published version of the respective specification.</p>
<!-- Normative and informative references follow automatically -->
</section>
<section id="references">, ReSpec still generates the references section automatically[[CITE]] usage throughout the document plus any localBiblio entries<section id="tof">📝 EditAutomatically generates a Table of Figures — a list of all <figure> elements in the document, linked to each figure by its <figcaption>.
<section id="tof">
<!-- ReSpec generates the list of figures here -->
</section>
<figure> elements with a <figcaption> are included — ReSpec auto-generates IDs from the caption text if no id is set<section id="tof" class="appendix"><a href="#figure-id"> links auto-fill with "Figure N"ReSpec supports dark mode for W3C specs via the standard color-scheme meta tag.
<head>
<meta name="color-scheme" content="light dark">
</head>
This uses the official W3C dark stylesheet from tr-design and respects the user's prefers-color-scheme preference.
The ReSpec pill includes a dark mode toggle that overrides the system preference. This toggle injects a .darkmode class on <body> via JavaScript.
Because the manual toggle uses a JavaScript-injected class rather than a CSS media query, custom CSS must target both approaches:
/* System preference */
@media (prefers-color-scheme: dark) {
.my-custom-element { background: #1a1a1a; }
}
/* ReSpec manual toggle */
body.darkmode .my-custom-element { background: #1a1a1a; }
.darkmode class limitation is a known architectural issue; the CSS prefers-color-scheme media query does not respond to JS-injected class names.darkmode class<figure>📝 EditStandard HTML <figure> elements are enhanced by ReSpec with automatic numbering, self-links, and cross-reference support.
<figure id="flowchart">
<img src="flowchart.svg" alt="Water flows from bucket A to bucket B" />
<figcaption>The water flows from bucket A to bucket B.</figcaption>
</figure>
<p>As shown in <a href="#flowchart"></a>, the flow is one-directional.</p>
The empty <a href="#flowchart"> auto-fills with "Figure N" text.
<figcaption> is required — figures without one generate a ReSpec warningid auto-populate with "Figure N"§) is generated so readers can link directly to a specific figuretof (Table of Figures)<figcaption> should be a proper caption describing the figure, not just a title<h1 id="title">📝 EditThe <title> element is the recommended way to set a spec title, but when you need markup in the title (e.g., for internationalization or code formatting), use a single <h1 id="title"> element in the body.
<body>
<h1 id="title">The <code>Widget</code> Interface</h1>
<section id="abstract">
<p>This spec defines the Widget interface.</p>
</section>
</body>
<title> element text and the <h1 id="title"> text content don't match — keep them in sync<h1 id="title"> is allowed<title> element is still required for the HTML document — the <h1> overrides the rendered title only<pre> and <code> elements📝 EditReSpec automatically syntax-highlights <pre> and <code> elements using highlight.js. Highlighting runs in a Web Worker — it doesn't block the main thread.
<pre>
function fetch(url) {
return new Promise(resolve => {
// ... JS is auto-detected
});
}
</pre>
<pre class="css">
.widget {
display: flex;
color: #336;
}
</pre>
abnf, css, html, http, javascript (js), json, xml, webidl
<pre class="nohighlight">
pseudocode or plain text here
</pre>
async function loadSolidity() {
const worker = await new Promise(resolve => {
require(["core/worker"], ({ worker }) => resolve(worker));
});
worker.postMessage({
action: "highlight-load-lang",
langURL: "https://example.com/highlightjs-solidity.js",
propName: "hljsDefineSolidity",
lang: "solidity",
});
return new Promise(resolve => {
worker.addEventListener("message", function listener({ data }) {
if (data.action === "highlight-load-lang" && data.lang === "solidity") {
worker.removeEventListener("message", listener);
resolve();
}
});
});
}
var respecConfig = {
preProcess: [loadSolidity],
};
nohighlight to disable for a blocknolinks to prevent auto-linking of URLs inside code blocks (Markdown mode)<section>📝 EditStandard HTML <section> elements are the building blocks of a ReSpec specification. ReSpec handles heading numbering, ToC generation, ID creation, and self-links automatically.
<section>
<h2>The <code>fetch()</code> method</h2>
<p>The <code>fetch()</code> method initiates a network request.</p>
</section>
<section>
<h2>Infrastructure</h2>
<section>
<h2>Concepts</h2>
<p>This section defines key concepts.</p>
</section>
<section>
<h2>Algorithms</h2>
</section>
</section>
Links to a section's ID with no text content are automatically filled with "§ N.N Title":
<p>See <a href="#infrastructure"></a> for details.</p>
<!-- Renders as: See § 2 Infrastructure for details. -->
<h2> for all top-level sections by convention (ReSpec renumbers them correctly regardless)<h6> — ReSpec clamps to <h6> for deep nestingid attributes manually for stable URLs; ReSpec generates IDs from heading text if absentabstract, sotd, conformance, toc — these trigger specific boilerplateappendix for lettered appendix sectionsinformative to mark a section as non-normative<title>📝 EditThe <title> HTML element sets the title of the specification. ReSpec uses its content to generate the document's <h1> heading and the document header title block.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Payment Request API</title>
<!-- ... -->
</head>
<body>
<section id="abstract">
<p>This specification defines the Payment Request API.</p>
</section>
</body>
</html>
<title> is the simplest and recommended way to set the spec title<code> or non-ASCII characters), use <h1 id="title"> instead<title> and any <h1 id="title"> in sync — ReSpec warns if they differ.appendix📝 EditMarks a section as an appendix. Appendix sections are lettered rather than numbered (A, B, C…). All sections following an appendix are also treated as appendices.
<section class="appendix">
<h2>Acknowledgements</h2>
<p>The editors thank the following for their contributions…</p>
</section>
class="informative" if needed.ednote📝 EditMarks content as an Editor's Note — a note intended for reviewers and co-editors, not the final reader. Editor's Notes are typically removed before publication.
<p class="ednote">
This section needs to be revised to address the i18n WG feedback.
</p>
<div class="ednote" title="Open question">
<p>We haven't decided whether this algorithm should be async.</p>
<p>See <a href="https://github.com/example/spec/issues/42">issue #42</a>.</p>
</div>
title attribute adds text to the heading: "Editor's Note: [title]". It is interpreted as HTML.note, editor's notes signal work-in-progress and are not intended for the published specissue for tracked GitHub issues; use .ednote for free-form editorial comments.example📝 EditMarks a <pre>, <aside>, or other element as a numbered example. Adds an "Example N" heading with an optional title.
<pre class="example">
const result = navigator.credentials.get({ password: true });
</pre>
<aside class="example" title="Using the Fetch API">
<p>Here is how to make a request:</p>
<pre>
const res = await fetch("/data.json");
</pre>
</aside>
<pre class="illegal-example">
document.write("<!-- don't do this -->");
</pre>
§) is generated so readers can link directly to a specific exampletitle attribute is interpreted as HTML — see title attributesclass="illegal-example" to mark a counter-example (renders with a different style)<aside class="example"> can contain nested <pre> elements with mixed prose and code.exclude📝 EditOpts an element out of specific ReSpec processing.
<p>
<abbr class="exclude" title="Application Programming Interface">API</abbr>
is not automatically expanded here.
</p>
<aside class="example" title="Hypothetical API">
<pre class="idl exclude">
interface Example {
undefined hypotheticalMethod();
};
</pre>
</aside>
| Element | Effect of .exclude |
|---|---|
<abbr class="exclude"> |
Prevents the abbreviation from being automatically expanded |
<pre class="idl exclude"> |
Excludes this WebIDL block from the idl-index |
.exclude class does not prevent the element from being rendered — it only opts out of specific ReSpec transformationsdata-export / .export📝 EditApplies to: <dfn>
Marks a definition as exported — available for other specifications to cross-reference via xref. All WebIDL definitions are automatically exported; use this for prose concepts.
<p>The <dfn data-export>fetch</dfn> algorithm takes a request and returns a response.</p>
The class="export" form also works:
<dfn class="export">request</dfn>
<dfn data-noexport>internal algorithm</dfn>
data-export for IDLdata-noexport to explicitly prevent a definition from being exported (e.g. if it would shadow a same-named definition from another spec)<dfn> elements in <section id="abstract"> or other unnumbered sections (SotD, introductory sections). Doing so causes a crash in the terms index (bug #5133). Define terms in a numbered section such as a "Terminology" or "Definitions" section instead..informative📝 EditMarks a section as non-normative. ReSpec automatically prepends the standard "This section is non-normative." paragraph.
<section class="informative">
<h2>Background and Motivation</h2>
<p>This section explains the history behind this feature…</p>
</section>
class="appendix" for informative appendices: class="appendix informative"ednote sections are also non-normative and are typically stripped before publication.issue📝 EditMarks content as an open issue box. When used with github, can automatically embed a GitHub issue by number.
<div class="issue">
<p>We need to decide whether this should be synchronous.</p>
</div>
<div class="issue" data-number="363"></div>
<p class="issue" title="Needs resolution">
Should this be normative?
</p>
<div class="issue atrisk" data-number="42">
<p>This feature may be removed before publication.</p>
</div>
Adding class="atrisk" alongside class="issue" renders the heading as "(Feature at Risk) Issue N" — the W3C Process convention for marking features under review during CR.
When atRiskBase is configured, data-number links to that tracker instead of issueBase:
var respecConfig = {
issueBase: "https://github.com/example/repo/issues/",
atRiskBase: "https://github.com/example/repo/issues/",
};
data-number is set and github is configured, ReSpec downloads the issue content from GitHub and embeds itstate: "CLOSED" render with a closed CSS classtitle attribute is interpreted as HTML — see title attributes<span class="issue">…</span> renders as a compact inline issue markerissue-summary to generate a collected list of all issues in the documentlint-ignore📝 EditThe lint-ignore class suppresses specific linting warnings on individual elements without disabling the entire rule globally.
When no-unused-dfns is enabled, suppress for one definition:
<dfn class="lint-ignore">internal helper concept</dfn>
When informative-dfn is enabled, suppress for one link:
<a class="lint-ignore">informative concept</a>
lint-ignore is element-level — it only suppresses the warning on that specific element, not all occurrencesdata-lint-ignore="rule-name" (attribute form) for suppressing specific rules on tables and other elementsno-link-warnings (class)📝 EditAdding class="no-link-warnings" to a <pre class="idl"> block suppresses warnings about unlinked or undefined IDL terms within that block.
<pre class="idl no-link-warnings">
dictionary PointerEventInit : MouseEventInit {
long pointerId = 0;
double width = 1;
};
</pre>
.nohighlight📝 EditDisables syntax highlighting for a specific <pre> code block. By default, ReSpec syntax-highlights all <pre> elements.
<pre class="nohighlight">
This is plain text or pseudocode.
It will not be syntax-highlighted.
</pre>
.nohighlight, ReSpec uses highlight.js to auto-detect and highlight the language.nohighlight for pseudocode, ABNF grammars, or other content where syntax highlighting would be distracting<pre class="js"> for JavaScript, <pre class="css"> for CSS, etc..nolinks📝 EditDisables automatic URL hyperlinking within a <pre> element. When Markdown is used, ReSpec auto-links URLs — this class prevents that for code blocks where you don't want bare URLs turned into hyperlinks.
<pre class="nolinks">
const url = "https://example.com/data";
fetch(url); // https://example.com/data stays as text
</pre>
<a href> links are unaffected<pre class="js nolinks">.note📝 EditMarks content as a note. Generates a labelled "Note" box with the content.
<div class="note">
<p>Authors must not rely on the computed value being identical
across different implementations.</p>
</div>
<p class="note" title="Always use native semantics">
If you are using <code>role="button"</code> on a div,
you are probably doing it wrong.
</p>
| Class | Renders as |
|---|---|
.note |
Note box |
.note with title attribute |
"Note: [title]" header |
.warning |
Warning box (see .warning) |
<div>, <p>, <aside>, <section><span class="note">…</span> renders as a compact inline notetitle attribute is interpreted as HTML — see title attributesednote instead.notoc📝 EditExcludes a section from the Table of Contents.
<section class="notoc" id="acknowledgements">
<h2>Acknowledgements</h2>
<p>The editors thank...</p>
</section>
data-max-toc="0" has the same effect as class="notoc" but can be applied from data-include contextnoTOC config option.numbered (tables)📝 EditAdding class="numbered" to a <table> enables automatic numbering, caption linking, and inclusion in a Table of Tables.
<table class="numbered">
<caption>Browser support matrix</caption>
<thead>
<tr><th>Browser</th><th>Supported since</th></tr>
</thead>
<tbody>
<tr><td>Chrome</td><td>79</td></tr>
<tr><td>Firefox</td><td>97</td></tr>
</tbody>
</table>
<!-- Elsewhere: auto-fills with "Table N" -->
<a href="#ref-to-table-id"></a>
<section id="list-of-tables">
<!-- All numbered tables are listed here automatically -->
</section>
<caption> is required — the no-captionless-tables linting rule enforces this<caption> must be the first child of <table>id auto-fill with "Table N" textclass="numbered" are not auto-numbered or included in the List of Tables.override📝 Edit⚠️ Last resort only. Adding class="override" to a section that ReSpec would normally auto-generate replaces the generated content entirely with your custom content.
<section id="sotd" class="override">
<h2>Status of This Document</h2>
<p>This document is an experimental draft for discussion only.</p>
</section>
<section id="sotd"> — Status of This Document<section id="conformance"> — Conformancesotd bypasses the standard W3C status boilerplate — you are responsible for all required W3C publication text.override class — ReSpec will prepend the boilerplate and keep your content.permission / data-dfn-type="permission"📝 EditMarks a <dfn> as defining a browser permission string, as used in the Permissions API. The permission name should be a quoted string.
<p>
The Geolocation API is identified by the powerful feature name
<dfn class="permission">"geolocation"</dfn>.
</p>
Or equivalently:
<dfn data-dfn-type="permission">"geolocation"</dfn>
"geolocation", "camera")class="permission" is equivalent to data-dfn-type="permission".practice / .practicedesc / .practicelab📝 EditA set of CSS classes for marking up best practices in a specification. Generates a numbered best practice box with a label and description.
<div class="practice">
<p class="practicedesc">
<span class="practicelab">Use semantic HTML</span>
Use the most semantically appropriate HTML element for each piece of content.
Do not use `<div>` where a `<section>`, `<article>`, or `<nav>` would be more appropriate.
</p>
</div>
| Class | Applied to | Purpose |
|---|---|---|
.practice |
<div> |
Container for the best practice |
.practicedesc |
<p> |
The description text |
.practicelab |
<span> inside .practicedesc |
The label/name of the practice |
practicedesc📝 EditA paragraph containing the description of a best practice, inside a practice <div>.
<div class="practice">
<p class="practicedesc">
<span class="practicelab">Best practice</span>
Practice makes perfect, but perfect is the enemy of the good.
</p>
</div>
practicelab📝 EditA <span> containing the title of a best practice, inside a <p class=practicedesc>.
<div class="practice">
<p class="practicedesc">
<span class="practicelab">Best practice</span>
Practice makes perfect, but perfect is the enemy of the good.
</p>
</div>
.remove📝 EditMarks an element to be removed from the document during processing. This is how the ReSpec <script> elements and config blocks are handled — they are stripped after processing completes.
<div class="remove">
<p>This content is for authoring convenience only and won't appear in the output.</p>
</div>
<script src="respec-w3c.js" class="remove" async></script>
<script class="remove">
var respecConfig = { ... };
</script>
.remove class strips the element entirely from both the live preview and the saved HTML export.removeOnSave instead<script class="remove"> elements in a ReSpec document use this pattern.removeOnSave📝 EditMarks an element to be removed when the document is exported to static HTML (via "Save as HTML"). Use this for content that is useful during authoring but should not appear in the published spec.
<div class="removeOnSave">
<p class="ednote">Remember to update the SotD before publication.</p>
</div>
<p>
See <a href="https://respec.org/xref" class="removeOnSave">(xref search)</a>
for resolving ambiguous terms.
</p>
removeOnSave — it disappears from saved HTMLcaniuse and mdn widgets also use removeOnSave by default (configurable via removeOnSave option)class="removeOnSave" is fully removed — not just hidden — in the exported HTML<section id="sotd" class="updateable-rec">📝 EditMarks a Proposed Recommendation as intending to allow new features once it becomes a W3C Recommendation. ReSpec adds the required boilerplate text automatically.
<section id="sotd" class="updateable-rec">
<p>This specification may be amended by adding new features
in future levels.</p>
</section>
"PR" (Proposed Recommendation) documents heading toward "REC"specStatus and this classdata-abbr📝 EditApplies to: <dfn>
Automatically generates an <abbr> element after the definition, showing the abbreviation in parentheses. ReSpec generates the abbreviation from the term's initial letters if no value is provided.
<dfn data-abbr>user agent</dfn>
<!-- Renders as: user agent (UA) -->
<dfn data-abbr="PoS">point of sale</dfn>
<!-- Renders as: point of sale (PoS) -->
<abbr> element added uses the full term as its title attribute, enabling screen reader and hover tooltip supportdata-lt) on the <dfn>, so [=UA=] will link to the definition of "user agent" without needing a separate alias declarationdata-cite📝 EditApplies to: <a>, <dfn>
Manually links an element to a specific term, section, or spec. Use this when xref automatic linking doesn't work, or when you need a precise anchor.
data-cite📝 Edit| Situation | Use |
|---|---|
| Term is in the xref database | [=term=] shorthand (preferred) |
| Term is not exported by the defining spec | data-cite="SPEC#anchor" |
| Linking to a section heading (not a term) | data-cite="SPEC#section-id" |
| Linking to the spec itself (bibliography) | data-cite="SPEC" |
| Documenting a term defined elsewhere (re-exporting) | <dfn data-cite="SPEC#dfn-id"> |
data-cite="[!]SPEC-ID[/path-to-doc][#fragment]"
! — normative citation (omit for informative)SPEC-ID — shortname from SpecRef/path-to-doc — sub-path for multi-page specs#fragment — anchor ID in the target document<a data-cite="FETCH#concept-request">request</a>
<a data-cite="!FETCH#concept-request">request</a>
<p>The <dfn data-export data-cite="DOM#concept-event">event</dfn> is...</p>
<a data-cite="HTML#event-loop">event loop section of HTML</a>
<p>This is defined in [[FETCH]] — see <a data-cite="FETCH">the Fetch Standard</a>.</p>
<a data-cite="HTML/webappapis.html#event-loop">event loop</a>
<dfn data-cite> — re-exporting terms📝 EditWhen your spec needs to use and expose a term defined elsewhere, mark a local <dfn> with data-cite pointing to the canonical definition. This tells ReSpec where the term lives without defining it locally, and makes it linkable within your spec:
<!-- This lets other parts of your spec use [=request=] to link here -->
<p>A <dfn data-cite="FETCH#concept-request" data-export>request</dfn> is...</p>
[=term=] when the term is in the xref database — data-cite is for exceptionsdata-cite="SPEC" without a fragment, the spec is added to the bibliography automaticallydata-dfn-for📝 EditApplies to: <dfn>, <section>, <a>
Sets the context (scope) for a definition or link — typically the name of the IDL interface, dictionary, or element that a member belongs to. Also used on <section> to set the default context for all definitions and links within.
<section data-dfn-for="Request" data-link-for="Request">
<h2><code>Request</code> interface</h2>
<pre class="idl">
interface Request {
readonly attribute USVString method;
Promise<Response> clone();
};
</pre>
<p>The <dfn>Request</dfn> interface represents a resource request.</p>
<p>The <dfn>method</dfn> attribute returns the request method.</p>
<p>The <dfn>clone()</dfn> method returns a copy of the request.</p>
</section>
<dfn data-dfn-for="Request">method</dfn>
<dfn data-dfn-for="Response">type</dfn>
data-dfn-for on a <section> to apply the context to all <dfn> elements within that section (avoids repeating it on every dfn)data-link-for to set the default context for links within a section<pre class="idl"> automatically get data-dfn-for set from their parent interface; you only need this for the prose dfnsdata-dfn-type📝 EditApplies to: <dfn>
Declares the type of a definition. Used by the xref system to enable type-specific linking with [= =], {{ }}, and data-link-type.
In most cases you do not need this attribute — ReSpec infers the type automatically. IDL types (interface, method, attribute, etc.) are set automatically when a <dfn> is inside a <pre class="idl"> block.
<p>To <dfn data-dfn-type="abstract-op">process a widget</dfn>, run these steps:</p>
<p>The <dfn data-dfn-type="http-header">Widget-Policy</dfn> response header...</p>
| Value | Use for |
|---|---|
dfn |
General concepts and prose definitions (default when no type is set) |
abstract-op |
Abstract operations (algorithm steps) |
element |
HTML/SVG/MathML element names |
element-attr |
Content attributes of HTML/SVG elements |
attr-value |
Values of element attributes |
element-state |
States of elements (e.g. checkbox states) |
event |
DOM event types |
http-header |
HTTP header names |
media-type |
MIME types |
scheme |
URL schemes |
permission |
Permission strings (e.g. for the Permissions API) |
When <dfn> elements are inside a <pre class="idl"> WebIDL block, ReSpec automatically sets the dfn type from the IDL declaration. You don't set these manually:
interface, attribute, method, dictionary, dict-member, enum, enum-value, callback, typedef, namespace, constructor
[= term =] shorthand links to dfn or abstract-op type definitions{{ term }} shorthand links to IDL type definitionsdata-dfn-for is set, type defaults to IDL unless explicitly overriddendata-dfn-type and let ReSpec infer itdata-format📝 EditApplies to: <section> and other block elements
Marks the content of an element as Markdown, overriding the document's default format for that element. Use this to mix Markdown sections in an otherwise HTML document.
<section data-format="markdown">
## Introduction
This is **Markdown** content inside an HTML document.
- List item one
- List item two
</section>
"markdown" as a value<section> elements automaticallydata-include and data-include-format="markdown"data-include📝 EditApplies to: any element
Fetches an external file and inserts its content as children of the element (or replaces the element entirely with data-include-replace).
<section data-include="sections/introduction.html"></section>
<section data-include="sections/api.md"
data-include-format="markdown"></section>
<section data-include="sections/header.html"
data-include-replace="true"></section>
| Attribute | Description |
|---|---|
data-include-format |
Format of the included content: "html" (default) or "markdown" |
data-include-replace |
If present, the element is replaced rather than having content inserted into it |
data-oninclude |
Name of a function to call to transform the included content before insertion |
file:/// URLs. Use a local server during development.data-include-format📝 EditApplies to: elements with data-include
Specifies the format of the included content.
<section data-include="changelog.txt"
data-include-format="text"></section>
<section data-include="intro.md"
data-include-format="markdown"></section>
| Value | Behavior |
|---|---|
"html" |
Default. Content is inserted as HTML and processed by ReSpec. |
"markdown" |
Content is converted from GitHub Flavored Markdown to HTML before insertion. |
"text" |
Content is inserted as plain text (escaped, not parsed as HTML). |
"html" (default) fully processes the included content — WebIDL, definitions, xrefs all work"markdown" converts Markdown first, then processes the resulting HTML"text" is useful for including raw text like changelogs or ABNF grammars without HTML interpretationdata-include-replace📝 EditApplies to: elements with data-include
When present, the including element is replaced by the included content rather than having the content inserted inside it.
<div data-include="intro-section.html"
data-include-replace="true">
<!-- This entire <div>, including its opening and closing tags,
is replaced by the included file's content -->
</div>
<section data-include="content.html">
<!-- content.html's markup is placed here, inside the <section> -->
</section>
<section data-include="full-section.html"
data-include-replace="true">
<!-- The <section> element itself is replaced by full-section.html's content -->
</section>
<section>)data-include-replace, you'd end up with nested <section> elements"true", "1", or just the presence of the attribute)data-link-for📝 EditApplies to: <a>, <section>, <p>, other elements
Sets the default lookup context (scope) for links — matches definitions that have a corresponding data-dfn-for. Use this when two interfaces have members with the same name.
<!-- Link to Request's url, not Response's url -->
<a data-link-for="Request">url</a>
<!-- Preferred shorthand: -->
[= Request/url =]
{{ Request/url }}
<section data-link-for="Request">
<p>The <a>method</a> attribute returns the HTTP method.</p>
<p>The <a>url</a> attribute returns the request URL.</p>
</section>
data-link-for on a <section> (or <p>) to apply the scope to all links within it — avoids repeating on every <a>[= Interface/member =] and {{ Interface/member }} shorthands are preferred over data-link-for on individual linksdata-dfn-for to set scope on definitions (not links)[= =] and {{ }} syntaxesdata-link-type📝 EditApplies to: <a>
Constrains a link to match only definitions of a specific type. Mostly set automatically by the shorthand syntax — you rarely need to set this manually.
| Value | Use for | Shorthand |
|---|---|---|
"dfn" |
Prose concept definitions | [= term =] |
"idl" |
WebIDL definitions | {{ term }} |
"biblio" |
Bibliography references | [[SPEC]] |
"element" |
HTML/SVG element names | [^ element ^] |
[= =], {{ }}, and [[]] shorthands add data-link-type automatically — prefer shorthands over setting this attribute manuallydata-link-type is set on an <a>, ReSpec infers the type from context (inside a WebIDL block → IDL; in prose → dfn)data-local-lt📝 EditApplies to: <dfn>
Defines alternative linking terms that work within this document only — they are not exported to the xref database. Use this when you want local shorthand aliases for an exported term without polluting the cross-spec namespace.
<dfn data-export
data-lt="installed web application"
data-local-lt="installing|installation">installed</dfn>
<!-- All of these link correctly within this document: -->
<a>installed</a> <!-- exported, linkable cross-spec -->
[=installed web application=] <!-- exported -->
<a>installing</a> <!-- local only -->
<a>installation</a> <!-- local only -->
|data-lt alternatives are exported (the first data-lt value becomes the canonical xref export name)data-local-lt for verb forms, gerunds, and other grammatical variants that shouldn't clutter the global xref namespacedata-lt📝 EditApplies to: <dfn>, <a>
Defines alternative linking terms for a definition (or an alternative text for a link). Multiple alternatives are separated by |.
<dfn data-lt="fetch a resource|fetching">fetch</dfn>
<!-- All of these now link to the same definition: -->
<a>fetch</a>
<a>fetch a resource</a>
<a>fetching</a>
[=fetch=]
[=fetch a resource=]
[=fetching=]
<a data-lt="fetch a resource">retrieve it</a>
data-lt becomes the canonical export name for cross-spec linkingpluralize and data-lt-no-pluraldata-lt replaces the element's text content as the term; data-local-lt adds alternatives only visible within this documentdata-local-lt for document-local alternativesdata-lt-no-plural📝 EditApplies to: <dfn>
Disables automatic pluralization for a specific definition when pluralize is enabled globally.
<dfn data-lt-no-plural>CSS</dfn>
<dfn data-lt-no-plural>API</dfn>
<!-- Without this, 'APIs' would auto-link even if that seems wrong -->
data-lt-noDefault📝 EditApplies to: <dfn>
Prevents the element's text content from being used as a linking term. Only the values defined in data-lt are used for linking. Useful for disambiguating two definitions that would otherwise have the same default link text.
<dfn>The Foo</dfn>
<!-- Links as "The Foo" -->
<dfn data-lt="alternative foo" data-lt-noDefault>The Foo</dfn>
<!-- Links only as "alternative foo" — "The Foo" text is ignored -->
data-lt-noDefault, having two <dfn> elements with the same text content would cause a disambiguation errordata-lt-noDefault lets you give a definition a unique programmatic name (via data-lt) while the display text can still match another definitiondata-max-toc📝 EditApplies to: <section>
Limits the ToC depth for this section subtree, without setting a global limit via maxTocLevel. Useful when some sections need deep nesting but their subsections shouldn't clutter the ToC.
<section data-max-toc="2">
<h2>Infrastructure</h2>
<section>
<h2>Concepts</h2> <!-- included in ToC -->
<section>
<h2>Details</h2> <!-- NOT in ToC (depth 3 > max 2) -->
</section>
</section>
</section>
<section data-max-toc="0">
<h2>Internal Notes</h2> <!-- NOT in ToC -->
</section>
data-max-toc="0" is equivalent to class="notoc" — the section and all its children are excluded from ToCmaxTocLevel for a document-wide depth limitdata-number📝 EditApplies to: <p class="issue">, <div class="issue">
Links an inline issue box to a specific GitHub issue number. Requires github to be configured. The issue is titled "Issue N" with a link to the GitHub issue thread.
<p class="issue" data-number="42">
<!-- ReSpec fetches and displays the content of issue #42 -->
</p>
data-number is set, ReSpec fetches the issue content from GitHub and embeds it automaticallydata-number, you can still use class="issue" for inline editorial notes without a GitHub linkissue for full documentation of issue boxesdata-oninclude📝 EditApplies to: elements with data-include
A space-separated list of globally-defined JavaScript function names to call on the included content before it is inserted into the document. Each function transforms the raw content string.
<script>
function addTimestamp(utils, content, url) {
return content + `\n<!-- Included from ${url} -->`;
}
</script>
<section data-include="section.html"
data-oninclude="addTimestamp">
</section>
Each transform function receives:
| Argument | Type | Description |
|---|---|---|
utils |
Object |
ReSpec utility functions |
content |
string |
The raw included content as a string |
url |
string |
The URL of the included file |
The function must return the (possibly modified) content string.
<script class="remove"> block)data-sort📝 EditApplies to: <ol>, <ul>, <dl>
Sorts the top-level items of a list alphabetically. Useful for dependency sections, IDL member definitions, glossaries, and any list that should stay alphabetically ordered.
<ul data-sort>
<li>Banana</li>
<li>Apple</li>
<li>Cherry</li>
</ul>
<dl data-sort="descending">
<dt>Banana</dt><dd>A yellow fruit.</dd>
<dt>Apple</dt><dd>A red or green fruit.</dd>
<dt>Cherry</dt><dd>A small red fruit.</dd>
</dl>
| Value | Sorts |
|---|---|
"ascending" |
A → Z (default when attribute has no value) |
"descending" |
Z → A |
<dl>, the <dt> is used as the sort key; associated <dd> elements move with their <dt>Intl.Collator)data-tests📝 EditApplies to: <p>, <li>, and other elements containing testable assertions
Links one or more WPT test files to a prose assertion. Creates a collapsible "Tests" detail box on the element.
<script>
var respecConfig = {
testSuiteURI: "https://wpt.fyi/payment-request/",
};
</script>
<p data-tests="payment-request-basics.https.html, timeout.html">
The user agent MUST reject the Promise if the user cancels.
</p>
testSuiteURItestSuiteURI must be set in respecConfig — ReSpec will warn if it's missingwpt-tests-exist linting rule to verify all referenced tests actually exist in WPT<p> and <li> elements containing normative assertionsdata-type📝 EditApplies to: <var>
Declares the type of a variable in an algorithm. Used with the highlightVars feature to associate a type annotation with a variable.
<p>Let <var data-type="Request">request</var> be a new request.</p>
The |variable:Type| shorthand is equivalent:
<p>Let |request:Request| be a new request.</p>
|variable:Type| shorthand supports simple type names; for complex types (e.g., "valid" or "invalid") use the full <var data-type="..."> HTML syntax|variable:Type| syntaxdir📝 EditType: string
Default: "ltr"
Sets the text directionality of the document. Corresponds to the dir attribute on the <html> element.
<html lang="ar" dir="rtl">
<html> element, not in respecConfiglang attribute"ltr" (left-to-right), "rtl" (right-to-left), "auto"lang📝 EditType: string
Default: "en"
Sets the language of the document. Corresponds to the lang attribute on the <html> element.
<html lang="fr">
<html> element, not in respecConfig"en", "fr", "zh-Hans", "ar")dir attribute for RTL languages<rs-changelog>📝 EditA custom HTML element that shows a list of Git commits between two commit hashes or tags. Useful in Status of This Document sections to summarize changes since the last publication.
Requires github to be configured.
<p>Changes since the CR snapshot:</p>
<rs-changelog from="CR"></rs-changelog>
<rs-changelog from="v1.0" to="v2.0"></rs-changelog>
<rs-changelog from="CR" path="payment-request/index.html"></rs-changelog>
<script>
function filterChangelog(commit) {
// Return true to include, false to exclude
return !commit.message.startsWith("chore");
}
</script>
<rs-changelog from="CR" filter="filterChangelog"></rs-changelog>
| Attribute | Required | Description |
|---|---|---|
from |
Yes | Starting commit hash or tag (inclusive) |
to |
No | Ending commit hash or tag (inclusive). Defaults to latest commit. |
filter |
No | Name of a global JS function (commit) => boolean to filter commits |
repo |
No | Override the GitHub repo from respecConfig.github (useful for monorepos) |
path |
No | Only show commits touching this file or directory |
The filter function receives a commit object:
| Property | Type | Description |
|---|---|---|
hash |
string |
Abbreviated commit hash |
message |
string |
Commit message headline |
Return true to include the commit, false to exclude it.
document.respec📝 EditReSpec adds a respec object to document when it loads. Use it to wait for processing to complete, inspect errors and warnings, or export the processed HTML.
document.respec.ready📝 EditA Promise that resolves when ReSpec finishes all processing (including postProcess functions).
<script>
document.addEventListener("DOMContentLoaded", async () => {
await document.respec.ready;
console.log("Errors:", document.respec.errors);
console.log("Warnings:", document.respec.warnings);
});
</script>
document.respec.errors📝 EditAn array of errors found during processing.
document.respec.warnings📝 EditAn array of warnings found during processing.
Each item in errors and warnings has:
| Property | Type | Description |
|---|---|---|
message |
string |
The error/warning message text |
plugin |
string |
Name of the ReSpec plugin that generated it (e.g. "core/xref") |
hint |
string |
Optional suggestion for how to fix it |
title |
string |
Short form of the message (used as element tooltip) |
elements |
HTMLElement[] |
The offending elements in the document, if applicable |
details |
string |
Additional context or explanation |
cause |
object |
The underlying error that caused this one, if any |
document.respec.version📝 EditThe current ReSpec version string (semver, e.g. "35.8.0").
document.respec.toHTML()📝 EditReturns a Promise that resolves with the fully-processed document markup as a string — the same output as "Save as HTML".
<script>
document.addEventListener("DOMContentLoaded", async () => {
await document.respec.ready;
const html = await document.respec.toHTML();
// Send to a server, save to disk, etc.
await fetch("/save", { method: "POST", body: html });
});
</script>
await document.respec.ready before reading errors/warnings — the arrays are populated incrementally during processingdocument.respecIsReady was a bare Promise on document; the modern form is document.respec.readyaddPatentNote📝 Edit⚠️ Deprecated and removed. This option is no longer supported.
If you need patent-related notes, write them directly into the <section id="sotd"> (Status of This Document) section.
processVersion📝 Edit⚠️ Removed in ReSpec v19.5.0 (2018). Do not use.
ReSpec automatically uses the current W3C process. There is no longer any need to specify processVersion.
If you have processVersion in your config, remove it — it has no effect.
tocIntroductory📝 Edit⚠️ Deprecated and removed. Use the .notoc CSS class instead, or data-max-toc on individual sections.
Previously caused introductory sections (Abstract, SotD, etc.) to appear in the Table of Contents.
wg📝 Edit⚠️ Deprecated. Use group instead.
Previously used to set the full name of the Working Group. The group option replaces this and all related wg* options — it auto-configures the group name, patent policy, homepage, and mailing list from a single short name.
var respecConfig = {
wg: "Web Payments Working Group",
wgURI: "https://www.w3.org/groups/wg/payments/",
wgPatentURI: "https://www.w3.org/groups/wg/payments/ipr",
wgPublicList: "public-payments-wg",
};
var respecConfig = {
group: "payments",
};
See group for the full list of available group short names.
wgId📝 Edit⚠️ Deprecated. Use group instead.
Previously used to specify the numeric W3C Working Group identifier. The group option replaces this automatically.
// Before:
// wgId: 107714,
// After:
var respecConfig = {
group: "webapps", // short name — see respec.org/w3c/groups/
};
wgPatentURI📝 Edit⚠️ Deprecated. Use group instead.
Previously used to set the URL of the Working Group's patent disclosure page. The group option auto-configures the correct patent policy URI.
This was error-prone — copying from another spec often resulted in the wrong patent policy URL being used, with legal implications.
// Before (error-prone):
// wgPatentURI: "https://www.w3.org/2004/01/pp-impl/83482/status",
// After (auto-configured correctly):
var respecConfig = {
group: "webapps",
};
wgURI📝 Edit⚠️ Deprecated. Use group instead.
Previously used to set the URL of the Working Group's public page. The group option auto-configures this.
// Before:
// wgURI: "https://www.w3.org/groups/wg/webapps/",
// After:
var respecConfig = {
group: "webapps",
};
xref.caniuse feature.wpt-tests-existA person object is used by editors, authors, and formerEditors. Only name is required.
var respecConfig = {
editors: [
{
name: "Alice Smith",
url: "https://alice.example/",
company: "Example Corp",
companyURL: "https://example.org/",
w3cid: 12345,
orcid: "https://orcid.org/0000-0001-2345-6789",
note: "Invited Expert",
extras: [
{
name: "Personal blog",
href: "https://alice.example/blog",
class: "blog",
}
],
},
],
};
| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Full name of the person |
url |
string |
No | Personal URL. Use mailto:[email protected] for email links. |
company |
string |
No | Employer or affiliation |
companyURL |
string |
No | URL of the employer |
w3cid |
number |
No | W3C account ID. Find yours at w3.org/users/myprofile. Enables contributor stats. |
orcid |
string |
No | ORCID iD — full URL or bare ID (e.g. 0000-0001-2345-6789). Displays an ORCID icon. |
note |
string |
No | Short text shown in parentheses after the name (e.g. "Invited Expert", "until 2023") |
extras |
Extra[] |
No | Additional links shown after the person entry |
retiredDate |
string |
No | "YYYY-MM-DD" — marks the person as retired from this date. Shows them as "until [date]". |
extras format📝 EditEach entry in extras is an object:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Link text (may contain HTML) |
href |
string |
No | URL for the link |
class |
string |
No | CSS class(es) on the resulting element |
w3cid is strongly recommended for W3C documents — it links the editor to their W3C profileorcid can be a full URL (https://orcid.org/0000-…) or just the identifier (0000-…)retiredDate is useful for keeping a former editor listed inline while showing when they leftThis page lists some common ReSpec errors and their mitigation.
To fix this issue, follow these steps:
Is the term defined in some other document/specification?
xref's specs.<dfn> should have a "export" css class.data-cite attribute to reference those terms.Is the term defined in same document?
data-link-for.data-link-for.As a first step, clone the repository:
git clone [email protected]:speced/respec.git
Developing ReSpec requires Node.js v18.14+ and pnpm v8+. You can "install" pnpm with corepack as:
corepack enable
corepack prepare --activate # run this from repository root
and install the needed dependencies:
pnpm install
Now you can start the local development servers:
pnpm start --browser Chrome
Note: You can use Firefox and ChromeCanary in the above.
That will start up "Karma" and a local http server for you.
Open the url given (usually http://127.0.0.1:8000). And go to "examples".
Usually "basic.html" is a good place to start hacking from.
ReSpec is an application that runs mostly synchronous bits of JS after a Document loads. These JavaScript fragments are referred to as "plugins". When a bunch of plugins are combined together, they create a "profile".
Generally, a "profile" is only created for a real-world organization or company. So, for instance, the W3C's profile, located at profiles/w3c.js, loads the following plugins (not the full list, just for illustrative purposes):
What each plugin above does doesn't matter, though you can deduce what each does by the name. What matters is that ordering is important - and we mix together W3C plugins and "core" plugins. And that it's these plugins coming together that form a profile, in this case the "W3C profile". Each of the plugins are run only once - and the thing that runs them is the core/base-runner plugin.
See profile/w3c.js for the actual details of how the profile is set up. But it's essentially:
The first and most important plugin (core/base-runner), is actually the "brains" of ReSpec: it is the thing that "runs" all other plugins in order.
Before any plugins are run, however, it adds the following property to the document object:
// The following only resolves once all plugins have run
// and ReSpec has finished doing whatever it needs to do.
document.respec.ready;
After that, the Base Runner starts looping over an array of given plugins: literally just a call to a .runAll(arrayOfPlugins) method. For each plugin, it waits until a plugin has finished doing its work before continuing to the next plugin. It does this by calling the run() function exported from a plugin, and awaiting for that function to finish. Some plugins may export a Plugin class with a run() method instead.
Once all the plugins have "run", ReSpec resolves the respec.ready promise on the Document object.
document.respec.ready.then(() => {
console.log("ReSpec has finished processing this document");
});
This is potentially useful for scripts that depend on ReSpec's output. They can wait for the promise to settle before doing their own work.
Alternatively, if you really need to run things immediately before or after ReSpec runs the plugins, you can define preProcess or postProcess properties on the configuration object. See preProcess and postProcess more details and for examples.
Plugins are simple ES6 modules that live in the "src/" folder. They have two parts: A synchronous initialization, and an optionally exported run() function that is called asynchronously.
A plugin looks like this:
// import other things you need
import utils from "core/utils";
// This part runs synchronously and an indeterminate order.
// do any plugin specific setup here. Note, the document
// can be in an unstable state here - so don't manipulate
// the DOM here!
// Optionally, export "run" function
// See below for description of arguments.
export async function run(conf) {
if ("something" in conf || document.querySelector("#important-element")) {
await someAsyncTask();
}
}
async function someAsyncTask() {
// Your code here
}
The exported run method SHOULD have arguments (conf):
conf: is the ReSpec configuration object (window.respecConfig) - which the user defined. Be careful not to modify this object.If you are creating a plugin that needs to show warnings to a user, you can use the showWarning utility.
import { showWarning, showError } from "./core/utils.js";
export async function run(conf) {
if (!"something" in conf) {
showWarning("Some error message", "plugin-name");
// You can pass additional details like a `hint` how to fix, list of `elements` that caused the issue etc.
// See showWarning and showError in core/utils.js
}
}
These messages will be picked up by ReSpec's UI (the "pill"), and displayed to the end-user. You should only "error" on things that the user needs to fix to successfully publish their document. Likewise, only warn on things the user SHOULD fix.
IMPORTANT: Don't show JavaScript errors to the user - as they won't be able to fix these, and the minified JS output will make these messages really unhelpful!
The start script in package.json contains the commands useful during development. It runs a static HTTP server, watches files for change and re-build the profile, and run unit tests.
You can launch a built in HTTP server during development by simply typing: pnpm start.
If you wish not to run tests and other parts of start script, you can alternatively run pnpm run server.
ReSpec's unit tests are written using Jasmine and run on Karma. To start the testing server:
pnpm start --browser Firefox
You can run test in different browsers by setting browsers value above to any of: Firefox, FirefoxHeadless, Chrome, ChromeHeadless, Safari. Same can be set using the BROWSERS environment variable:
BROWSERS="ChromeHeadless Firefox" pnpm start
For debugging purposes, you can click on the Debug button when the tests start in the browser - this will allow you to see the tests summary in browser itself as well as allow you to re-run any particular test.
Please refer to Jasmine documentation regarding focused specs (fdescribe(), fit()) to see how to run only specific tests when running pnpm run karma. This will save you a lot of time and pain.
You can also select individual tests by filtering those which match a particular pattern:
pnpm start --grep="SEO"
If you want to run all tests whose description includes "SEO".
You can also run start in "interactive" mode. This gives you more control over when tests are run and, by default, turns off automatic file watching.
pnpm start --interactive
This is useful for more advanced debugging sessions, and can be combined with --grep to test just what you want, when you want.
You can also run tests without opening a full browser window. Test results will be visible in your terminal.
pnpm start --browser FirefoxHeadless
# or use ChromeHeadless
Look at the help dialog when you run pnpm start for more options.
If you are a company, standards consortium, or government entity, you might want to consider maintaining your own ReSpec profile. That allows you have your own content templates, load whatever plugins you need, and generally keep control over how ReSpec runs.
To create a custom profile:
node ./tools/builder.js YOUR-PROFILE-NAME. That will generate a bundle in the build directory.If the profile is popular, then please send a pull request to the main repository and we can host as part of the main project.
In examples/, make a copy of "basic.html" and point the <script> tag at your new profile. Now run:
pnpm start --profile YOUR_PROFILE_NAME --browser Chrome
That will start a web server, so you can now load up http://localhost:8000/examples and have play with your custom profile.
If you are writing custom Jasmine tests, simply place them into tests/spec/YOUR-PROFILE-NAME/. And then run:
pnpm start --interactive --profile=YOUR-PROFILE-NAME --browser Chrome
If you prefer to use a different browser, that's ok too.
This document is generated directly from the content of the ReSpec project wiki on GitHub. Thus, it can be edited in two ways:
src.html is available
in the
respec-web-services repository.