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 a HTML document that brings in the ReSpec script, defines a few configuration variables, and follows a few conventions. A very small example document would be:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Replace me with a real title</title>
<script
src="https://www.w3.org/Tools/respec/respec-w3c"
class="remove"
defer
></script>
<script class="remove">
// All config options at https://respec.org/docs/
var respecConfig = {
specStatus: "ED",
editors: [{ name: "Your Name", url: "https://your-site.com" }],
github: "some-org/mySpec",
shortName: "dahut",
xref: "web-platform",
group: "my-working-group",
};
</script>
</head>
<body>
<section id="abstract">
<p>This is required.</p>
</section>
<section id="sotd">
<p>This is required.</p>
</section>
<section class="informative">
<h2>Introduction</h2>
<p>Some informative introductory text.</p>
<aside class="note" title="A useful note">
<p>I'm a note!</p>
</aside>
</section>
<section>
<h2>A section</h2>
<aside class="example">
<p>This is an example.</p>
<pre class="js">
// Automatic syntax highlighting
function someJavaScript(){}
</pre>
</aside>
<section>
<h3>I'm a sub-section</h3>
<p class="issue" data-number="121">
<!-- Issue can automatically be populated from GitHub -->
</p>
</section>
</section>
<section data-dfn-for="Foo">
<h2>Start your spec!</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 by running
{{Foo/doTheFoo()}}.
</p>
<ol class="algorithm">
<li>A |variable:DOMString| can be declared like this.</li>
</ol>
</section>
<section id="conformance">
<p>
This is required for specifications that contain normative material.
</p>
</section>
</body>
</html>
The following code is used to include a ReSpec document, usually in the <head>:
<script src="https://www.w3.org/Tools/respec/respec-w3c" class="remove" defer>
</script>
<script class="remove">
var respecConfig = {
// configuration options
}
</script>
ReSpec is regularly updated and this will allow you to automatically benefit from bug and security fixes and enhancements.
ReSpec is configured using a JSON-like object, which is assigned to a respecConfig JavaScript variable:
<script class="remove">
var respecConfig = {
// configuration options
}
</script>
All the configurations options are listed in this document.
ReSpec documents are just HTML document and rely on HTML structural elements, in particular <section>, <aside>, <h2>-<h6>, <dl>, <ol> etc. In this section, we discuss how to specify various aspects of a typical document.
The <title> of the document is reused as the title of the specification in the resulting document's h1. That way, they are always in sync and you need not worry about specifying it twice.
<title>The Best Specification</title>
If you need to add additional markup to your title, you can still use a <h1> with id="title".
<h1 id="title">The <code>Foo</code> API</h1>
As with the title, you can also specify a subtitle as:
<h1 id="title">The <code>Foo</code> API</h1>
<h2 id="subtitle">Subtitle here</h2>
Which is rendered as:

You can also specify a subtitle configuration option in the ReSpec config, but using the markup above is preferred.
ReSpec-based specifications require you to wrap your content in <section> elements. We provide specific information and examples on how to use <section> elements.
Sections, subsections, appendices, and whatever other structural items are marked up in ReSpec using <section> elements.
<section>
<h2>A section</h2>
<p>Some text.</p>
<section class="informative">
<h3>I'm a sub-section</h3>
<p>Sub-section text.</p>
</section>
</section>
Which is rendered as:
As shown, sections are automatically numbered and uniquely id's for you. Use <section id="my-id"> specify your own id.
ReSpec sections understand some specific CSS classes: introductory, informative, and appendix.
Note: You can use the special syntax [[[#some-id]]] to link to a section.
In W3C specs, a table of contents (ToC) is generated automatically and placed after the "Status of This Document".
See also the maxTocLevel option to limit how deep the ToC is.
Set the configuration option noTOC to true to remove the table of content.
To include a figure, use the <figure> and <figcaption> elements. They automatically get an id and figure number.
<figure id="figure">
<img src="figure.svg" alt="W3C Logo" />
<figcaption>The W3C logo</figcaption>
</figure>
Which renders as:
Automatic linking to figures works just as it does for sections, with [[[#some-figure]]].
To add a "List of Figures", include <section id="tof"> anywhere in the document. ReSpec will do its best to guess if it should be an appendix, introductory, or just a regular section.
<section id="tof" class="appendix"></section>
Renders as:
Any <pre class="example"> or <aside class="example"> gets the additional example header and style. Content inside <pre>/<code> elements is syntax highlighted. You can specify the language in the class attribute, for example <pre class="js">.
<aside class="example" title="How to use it">
<p>
This is how to use it.
<p>
<pre class="js">
function myCoolFunction() {
// stuff goes here...
}
</pre>
</aside>
which is rendered as:
Including external content into ReSpec is done using the data-include attribute, which points to a URL.
<section data-include="some.html"></section>
You can specify data-include-format='text' to include content as text, and therefore only process it as much as text is expected to be. The only recognized value are "text", "markdown", and "html" (default).
Note: data-include relies on the browser's ability to retrieve the resource and is governed by CORS (and the browser's security model in general). Browsers will generally block cross origin request, which means file:// URLs will likely fail. For more information, please see "Cross-Origin Resource Sharing (CORS)". You can usually get around this by starting a local web server (e.g., by running python -m http.server 8000 from the command line).
Use data-oninclude to perform transformation on content included with data-include.
ReSpec specifications are RFC2119/RFC8174 keyword aware.
Adding a <section id="conformance"> tells ReSpec that the specification is dealing with "normative" statements. ReSpec can then warn if RFC2119 keywords are accidentally used in informative/non-normative contexts.
<section>
<h2>Requirements</h2>
<p>A user agent MUST do something.</p>
</section>
<section id="conformance"></section>
Renders as:
Mark abbreviations using <abbr title="abbreviation">abbr</abbr>. ReSpec will then wrap all matching instances abbreviations with <abbr>.
<p>
The <abbr title="World Wide Web">WWW</abbr>.
</p>
<p>
ReSpec will automatically wrap this WWW in an abbr.
</p>
To mark some text as code, use <code> or backticks (`).
To define a term, simple wrap it in a <dfn> element.
<dfn>some concept</dfn>
Then, to link to it, just do:
<a>some concept</a>
or
[=some concept=]
For simple/single nouns, ReSpec handles pluralization automatically:
<dfn>banana</dfn>
<!-- these are the same -->
These [=bananas=] are better than those <a>bananas</a>
Sometimes a defined terms needs additional related terms or synonyms. In those cases, you can use the data-lt attribute on the dfn element:
<dfn
data-lt="the best fruit|yellow delicious">
banana
</dfn>
Note: "lt" stands for "linked term".
The following all link back to "banana":
<p>[=the best fruit=] or the [=yellow delicious=].</p>
The powerful (xref) feature let's you reference terms and concepts in other specifications. For example, to reference "default toJSON steps" from the WebIDL standard:
<script>
var respecConfig = {
xref: ["WebIDL"],
};
</script>
<a>default toJSON steps</a>
To search for terms + specs your can link to, you can use the XREF UI at http://respec.org/xref/. Below is a screenshot of what the UI looks like:
There are two important shorthands for linking to definitions:
[=term=] for linking regular concepts, {{IdlThing}} for linking WebIDL.Shorthand syntax works for referencing external terms as well as locally defined terms. It's best practice is to use shorthands all the time.
<script>
var respecConfig = {
xref: ["webidl", "payment-request"],
};
</script>
<section>
<!--
Here, we reference the "default toJSON steps" concept defined in [[WebIDL]] standard,
and the PaymentRequest interface (WebIDL) defined in [[payment-request]] standard.
-->
<p>[=default toJSON steps=] for the {{PaymentRequest}} interface are ...</p>
<!-- We also define a concept "feline", and an interface "Cat". -->
<p>A <dfn>feline</dfn> has 4 legs and makes sound.</p>
<pre class="idl">
interface Cat {}
</pre>
<!-- ...and we can reference them as: -->
<p>A {{Cat}} is a [=feline=] if it meows.</p>
</section>
Read more about linking and other shorthands in the Shorthands Guide.
To reference another specification use the [[SPEC-ID]] syntax, where SPEC-ID is the referenced specification's in the Specref ecosystem - which includes most W3C, WHATWG, ECMA, and IETF documents.
When you reference a specification, your document automatically gets a bibliography section.
The [^link^] element is defined in the [[HTML]] spec.
Which renders as:
If you would like to reference a specification by its full name, you can use the three square brackets to "expand it":
<p>
The [^link^] element is defined in the [[[HTML]]].
</p>
Renders as:
ReSpec uses the context of the reference to work out if the reference is normative or informative: if the reference is in a section marked "informative", or an example, note, or figure, then ReSpec automatically makes the reference non-normative. Otherwise, the reference is treated as normative.
If you need a non-normative reference in a normative section, you can use a ? like so:
This is normative and MUST be followed. But, sometimes we need a non-normative
example reference [[?FOO]].
To escape a reference, use a backslash "[[\". For example, "[[\InternalSlot]]".
If a reference is missing, please submit it to Specref. This helps the whole community.
If that is not possible, you can use of the localBiblio configuration option to define your own references.
ReSpec supports adding additional links by specifying an otherLinks property in the configuration. The values for this configuration option are rich and complex, so are detailed in the reference section for otherLinks.
If you wish to add your own additional styles to your document, just use the regular <link> and <style> elements.
Some of ReSpec's configuration options can be specified in the query string, and they override the options specified in the source. For example, you can override the subtitle by, for example, doing the following: index.html?subtitle=This is a subtitle.
This is useful for quickly overriding configuration options without needing to directly edit the document itself (e.g., for the purpose of exporting a document draft with a different specStatus).
ReSpec provides useful options to handle the creation of the W3C boilerplate that goes into the "status of this document" and other key sections.
Specifications typically require having a "short name", which is the name used (amongst other places) in the canonical "https://w3.org/TR/short-name/" URLs. This is specified using the shortName option, as seen in the example above.
The group configuration option lets you state to which working/business/community group your specification belongs to. The list of group identifiers can be found at: https://respec.org/w3c/groups/.
Setting the group option sets the IPR Policy for your document, which is reflected in the "Status of this Document" section.
If your document is not intended to be on the W3C Recommendation Track, set noRecTrack to true.
The specStatus option denotes the status of your document, per the W3C Recommendation track. Typically, a status has implications in terms of what other options required. For instance, a document that is intended to become a Recommendation will require previousPublishDate and previousMaturity.
The specStatus section list all the possible status values.
By default, W3C specifications all get the regular W3C copyright notice. In some cases however, you will want to modify that.
For all document types, you can add your own copyright by using <p class="copyright">.
At times, the patent situation of a specification may warrant being documented beyond the usual boilerplate. In such cases, simply add your own <p> to the Status of this Document section.
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 way to code up your WebIDL is as follows:
<section data-dfn-for="ExampleInterface">
<h2><dfn>ExampleInterface</dfn> interface</h2>
<pre class="idl">
interface ExampleInterface {
void exampleMethod();
readonly attribute USVString url;
};
</pre>
<section>
<h2><dfn>exampleMethod()</dfn> method</h2>
<p>The {{ExampleInterface/exampleMethod()}} method steps are:</p>
<ol class="algorithm">
<li>Let |x| be ...</li>
</ol>
</section>
<section>
<h2><dfn>url</dfn> attribute</h2>
<p>The {{ExampleInterface/url}} attribute...</p>
</section>
</section>
<section>
<h2>Here is how you link!</h2>
<p>
The {{ExampleInterface}}
or the {{ExampleInterface/exampleMethod()}} method
or the {{ExampleInterface/url}} attribute.
</p>
</section>
Given interface Request {};, you can define the interface inside a heading like so:
<section>
<h2><dfn>Request</dfn> interface</h2>
<pre class="idl">
interface Request {};
</pre>
<p>An instance of {{Request}} allows you to make a request.</p>
</section>
The above provides convenient linking to the section where the interface is defined.
data-dfn-for📝 EditWhen defining things, the data-dfn-for creates child-parent relationships (e.g., a .method() is "for", or part of, SomeInterface).
For example, the following defines both the url and the clone method.
<section data-dfn-for="Request">
<h2>`Request` interface</h2>
<pre>
interface Request {
readonly attribute ByteString method;
readonly attribute USVString url;
};
</pre>
<p>The <dfn>clone()</dfn> method. The <dfn>url</dfn> attribute.</p>
<p>
Links to {{Request/clone()}} method. Links to the {{Request/url}} attribute.
</p>
</section>
If, for instance, you have two interfaces with methods or attributes that are the same:
<pre class="idl">
interface Request {
readonly attribute USVString url;
};
interface Response {
readonly attribute USVString url;
};
</pre>
You explicitly distinguish between them like so:
<section data-dfn-for="Request">
<p>
The <dfn>url</dfn> attribute of {{Request}} is used by {{Response/url}}.
</p>
</section>
<section data-dfn-for="Response">
<p>
The <dfn>url</dfn> attribute of {{Response}} depends on {{Request/url}}.
</p>
</section>
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 |
| 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 |
maxAge |
number |
86400000 |
Cache duration in milliseconds (default: 24 hours). Set to 0 for fresh data on every load. |
| 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: false
Enables click-to-highlight for <var> elements in algorithms. When a reader clicks a variable, all instances of that variable in the same algorithm are highlighted, making it easier to trace variable usage through long algorithms.
var respecConfig = {
highlightVars: true,
};
<var> elements: Let <var>request</var> be a new request.<ol> algorithm step list|variable| shorthand in Markdown mode 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-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-headingless-sections |
true |
Sections without a heading |
no-http-props |
true |
Non-HTTPS URLs in config |
no-link-warnings |
false |
Suppress all link warnings |
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 on the document using axe-core. Reports accessibility violations as ReSpec warnings.
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 },
},
},
},
};
Add ?a11y=true to the URL to temporarily enable all a11y rules without changing config.
color-contrast) are slow and disabled by default — enable them only when neededvar 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 make final modifications to the generated document, add custom markup, or run validation.
function addBuildInfo(config, document) {
const p = document.createElement("p");
p.textContent = `Built on ${new Date().toDateString()}.`;
document.querySelector("#sotd").append(p);
}
var respecConfig = {
postProcess: [addBuildInfo],
};
async function addVersionBadges(config, document) {
const links = document.querySelectorAll("a[data-needs-version]");
for (const link of links) {
const version = await fetchVersion(link.dataset.needsVersion);
link.textContent = `v${version}`;
}
}
var respecConfig = {
postProcess: [addVersionBadges],
};
Each function receives three arguments:
| Argument | Type | Description |
|---|---|---|
config |
Object |
The respecConfig object (plus internal ReSpec state) |
document |
Document |
The fully-processed ReSpec document |
utils |
Object |
ReSpec utility functions (e.g. for showing errors) |
postProcess appear in both the live preview and the saved HTML exportpreProcessrespecIsReadypreProcess📝 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, modify the DOM before ReSpec sees it, or set up configuration that depends on async operations.
async function loadFeatureData(config, document) {
const res = await fetch("/api/features.json");
const data = await res.json();
// Make data available to the spec
window.featureData = data;
}
var respecConfig = {
preProcess: [loadFeatureData],
};
function addDynamicSection(config, document) {
const section = document.createElement("section");
section.innerHTML = `<h2>Generated on</h2><p>${new Date().toDateString()}</p>`;
document.body.append(section);
}
var respecConfig = {
preProcess: [addDynamicSection],
};
Each function receives three arguments:
| Argument | Type | Description |
|---|---|---|
config |
Object |
The respecConfig object (plus internal ReSpec state) |
document |
Document |
The HTML document in its original, unprocessed form |
utils |
Object |
ReSpec utility functions (e.g. for showing errors) |
async functions are fully supportedpreProcess runs before structure, definitions, xref, and all other ReSpec processingpostProcesspublishDate📝 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📝 EditIf you wish feedback to your mailing list about this specific document to have a specific prefix subject in its subject line, then specify this (including the [ and ] if you want them). The various of the heading matter that refer to the mailing list will use this information.
var respecConfig = {
subjectPrefix: "[Foopy-Spec-Feedback]",
};
subtitle📝 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📝 EditThe URL of your test suite, gets included in the specification's headers.
var respecConfig = {
testSuiteURI: "https://example.com/test/suite/",
};
Also see: wpt-tests-exist lint rule.
xref📝 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>
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-cite on the elementdata-exportadditionalCopyrightHolders📝 EditFor regular documents, this is used to specify that additional parties hold a copyright jointly with W3C on this document. This is typically used when publishing documents that were developed in cooperation with other friendly standard consortia such as the IETF.
The option is simply some text giving the additional copyright holders. For unofficial documents, this string is used to replace the default CC license.
var respecConfig = {
additionalCopyrightHolders: "Internet Engineering Task Force",
};
You can preview this feature in live examples:
alternateFormats📝 EditShows links to alternate formats (such as PDF, ePub) in the document header.
This option accepts an array of objects, each of which has two required fields:
urilabelvar respecConfig = {
alternateFormats: [
{
label: "PDF",
uri: "https://example.w3.org/TR/example.pdf",
},
{
label: "XML",
uri: "https://example.w3.org/TR/example.xml",
},
],
};
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📝 EditThis configuration option must be specified for Interest Group Notes (IG-NOTE), where it must point at the disclosure section of the group charter, per publication rules. This option is ignored for all other documents.
var respecConfig = {
charterDisclosureURI: "https://www.w3.org/2019/06/me-ig-charter.html#patentpolicy",
};
copyrightStart📝 EditReSpec knows to include a copyright year that matches the publishDate in the copyright notice. However, for documents developed over a period of several years it is preferable to indicate the first year during which the copyright started by setting this option.
Note that this can always be safely specified since if copyrightStart is the same as the publishDate's year it is ignored.
The following appears as "Copyright © 1977-2016".
var respecConfig = {
copyrightStart: 1977,
publishDate: "01-01-2016",
};
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📝 EditAn URL to a document capturing errata for the specification. Generally, this only applies to documents with a "REC" and "PER" specStatus.
var respecConfig = {
status: "REC",
errata: "https://www.w3.org/XML/xml-V10-5e-errata",
};
group📝 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
};
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📝 EditThe URL of the implementation report (documenting how your test suite fares with implementations). It gets included in the specification's headers.
var respecConfig = {
implementationReportURI: "https://example.com/imp-report/",
};
latestVersion📝 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📝 Edit"Leveled" specs are generally specs that build on each other in a backwards compatible way. They generally include the text from each previous level. This is used a lot by the W3C's CSS Working Group.
Note: Refrain using a level unless you've considered all the implications of doing so. Levels can be very hard to maintain, specially if levels are evolving concurrently.
The level configuration options automatically appends the level to your spec’s title and shortName. The level is an integer value greater than or equal to 0.
var respecConfig = {
level: 2,
shortName: "payment-request",
};
Which results in:
Level 2 is appended to the title, so Payment Request Level 2.payment-request-2.Which would render as, for example:

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📝 EditSometimes it happens that a document is moved in the version control system, passed from one group to another, or split into several smaller documents. In such cases since the version control information is harder to find, this option can be used to point to a previous Editor's Draft. Rarely used.
var respecConfig = {
prevED: "https://example.com/old/ed",
};
previousDiffURI📝 EditWhen producing a diff-marked version, ReSpec uses the previousURI as the old version by default. Use this configuration option if you wish to override this to a specific URL.
var respecConfig = {
previousURI: "https://www.w3.org/TR/2014/WD-FOO-20140327/",
// Diff against the first version instead
previousDiffURI: "https://www.w3.org/TR/2014/WD-FOO-20130101/",
};
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📝 EditIf you are working on a new version of an existing Recommendation, use this to indicate what its shortName was.
var respecConfig = {
shortName: "fancy-feature-l2",
prevRecShortname: "fancy-feature",
};
prevRecURI📝 EditIf you are working on a new version of an existing Recommendation, use this to indicate what its URL was.
If a prevRecURI is not specified but prevRecShortname is, the latter will be used to generate the former by prefixing "https://www.w3.org/TR/" to it. Note however that while in the overwhelming majority of cases this works, it is not recommended to use this approach since if the Recommendation is later Rescinded, the link will be stale. Instead, use the dated link to the Recommendation.
var respecConfig = {
prevRecURI: "https://www.w3.org/TR/2014/example-20140327/",
};
submissionCommentNumber📝 EditAllows W3C staff to link to a comment number.
var respecConfig = {
specStatus: "Member-SUBM",
submissionCommentNumber: "03",
};
Which shows up as:
<a href="https://www.w3.org/Submission/2018/03/Comment/">
W3C Team Comment
</a>
wgPublicList📝 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.
<section id="conformance">
<p>This specification defines conformance criteria that apply
to a single product: the <em>widget</em>.</p>
</section>
gh-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>
<pre class="idl"> block in the document and combines themindex📝 EditAdding a <section id="index"> in your document instructs ReSpec to gather all the terms defined in your specification, as well as all the terms referenced by your specification into a single section. The index lets you conveniently search for all defined/referenced terms, as well as find their usage in the document.
<section id="index" class="appendix">
<!-- All the terms will magically appear here -->
</section>
You can also add a custom header and content to your index:
<section id="index" class="appendix">
<h2>List All The Terms!</h2>
<p>Wow, that's a lot of terms!</p>
<!-- All the terms will magically appear here -->
</section>
If you'd lie to show the full spec/document's title in the index, you can add the special "prefer-full-spec-title" CSS class, like so:
<section class="prefer-full-spec-title appendix" id="index">
So, for example, instead of "[DOM]", the document will show "DOM Standard" in the index.
<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 documentreferences📝 EditYou can add an explicit <section id="reference"> in cases where you need to add custom content to the references section of a document.
<section id="references">
<p>Citations are great!</p>
<!-- normative and informative references will appear below -->
</section>
<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> and an id are included<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 — tables without captions trigger the no-captionless-tables linting ruleid auto-populate with "Figure N"tof (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>
title 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 codeexclude📝 EditThe exclude CSS class allows HTML tags to opt-out of being processed by ReSpec.
It is only supported on the following elements:
<abbr class="exclude">TEXT</abbr> - excludes the element from automatic abbreviation generation, such that TEXT won't be wrapped in <abbr>. <pre class="idl exclude">, excludes the WebIDL block from the IDL index. This is useful if you want to have an WebIDL example that is not actually part of your specification.Some examples of usage:
<p>
<abbr class="exclude" title="Ay-Bee-See">ABC</abbr>,
but this won't be wrapped ABC.
</p>
<aside class="example" title="A hypothetical API">
<pre class="idl exclude">
interface ItsTwentyTwenty {
undefined cantSeeNobody();
};
</pre>
</aside>
data-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).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>
data-number is set and github is configured, ReSpec downloads the issue content from GitHub and embeds ittitle attribute is interpreted as HTML — see title attributesissue-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 |
<div>, <p>, <aside>, <section>title 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 Tablesoverride📝 EditWarning: only use this as a last resort. This feature is not recommended.
The override css class allow spec editors to completely override a section that would normally be dynamically filled with ReSpec generated content.
Sections you can override include:
<section id="sotd"><section id="conformance"><section id="sotd" class="override">
<h2>Status of this document</h2>
<p>Exploring new ideas...</p>
</section>
permission📝 EditThe permission class is used to define a browser permission.
<p>
The Geolocation API is a default powerful feature identified by the
name `<dfn class="permission">"geolocation"</dfn>`.
</p>
practice📝 EditA <div> containing a best practice description.
<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>
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📝 EditIf you want to include content that is used during the generation of the specification but must be removed from the output, then add the remove class to it. That is used for instance for all the script elements that pull in ReSpec and define its configuration.
<div class="remove">
<p>This will be removed at build time.</p>
</div>
.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 HTMLupdateable-rec📝 EditFor W3C Proposed Recommendations, declaring class="updateable-rec" on the Status of This Document <section> indicates the specification intends to allow new features once it becomes a W3C Recommendation. This will include the appropriate boilerplate text for you.
<section id="sotd" class="updateable-rec">
<p>Other status related stuff here...</p>
</section>
data-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 support<a> links are not automatically given the <abbr> treatmentdata-cite📝 EditApplies to: <a>, <dfn>
Manually links an element to a specific term or section in another specification. Use this when xref automatic linking doesn't work or when you need to link to a specific fragment.
Note: Prefer automatic xref linking where possible. data-cite is for cases where the term isn't in the xref database or when you need a precise anchor.
data-cite="SPEC-ID[/path-to-doc]#fragment"
SPEC-ID — the spec's shortname from SpecRef (e.g. "FETCH", "HTML")/path-to-doc — optional sub-path within a multi-page spec#fragment — the anchor ID in the target documentPrefix with ! to make the citation normative: data-cite="!FETCH#concept-fetch"
<a data-cite="FETCH#concept-request">request</a>
<a data-cite="!FETCH#concept-request">request</a>
<dfn data-cite="DOM#concept-event">event</dfn>
<a data-cite="FETCH">the Fetch Standard</a>
<a data-cite="HTML/webappapis.html#event-loop">event loop</a>
data-cite="SPEC" without a #fragment links to the spec itself and adds it to the bibliographydata-cite="SPEC#fragment" links to the exact anchor — the element's text becomes the link textdata-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, access errors/warnings, or export the processed HTML.
document.respec.isReady📝 EditA Promise that resolves when ReSpec finishes all processing.
<script>
document.addEventListener("DOMContentLoaded", async () => {
await document.respec.isReady;
console.log("ReSpec done!", document.respec.errors);
});
</script>
document.respec.errors📝 EditAn array of errors found during processing. Each item has:
| Property | Type | Description |
|---|---|---|
message |
string |
Error message text |
plugin |
string |
Name of the ReSpec plugin that generated the error |
hint |
string |
Optional hint for how to fix the error |
document.respec.warnings📝 EditSame structure as errors, but for warnings.
document.respec.toHTML()📝 EditReturns a Promise that resolves with the fully-processed document markup as a string — the same output produced by "Save as HTML".
<script>
document.addEventListener("DOMContentLoaded", async () => {
const html = await document.respec.toHTML();
console.log("Processed HTML length:", html.length);
});
</script>
isReady before reading errors/warnings since they may not be populated yetdocument.respecIsReady was a Promise directly on document — the modern document.respec.isReady is preferredaddPatentNote (Deprecated)📝 EditThis is no longer supported by ReSpec. Please write any patent-related notes directly into the "Status of This Document" section instead.
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📝 EditWarning: This is deprecated and has been removed. Use the .notoc CSS class instead.
A boolean, which when set to true, will cause the introductory sections to also show up in the table of contents. This is rarely needed, but some groups prefer to have it.
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.