ReSpec Documentation

More details about this document
Latest published version:
https://www.w3.org/respec/
History:
Commit history
Editor:
ReSpec
Feedback:
GitHub speced/respec (pull requests, new issue, open issues)
Edit this documentation
GitHub Wiki
Single Page

Abstract

ReSpec makes it easier to write technical documents. It was originally designed for writing W3C specifications, but now supports many output formats.

1. Getting Started📝 Edit

A ReSpec document is an HTML file that brings in the ReSpec script, defines a configuration object, and follows a few conventions. Open it in a browser over HTTP and ReSpec transforms it into a properly formatted specification.

1.1 A complete example📝 Edit

Example 1: A complete ReSpec specification
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>My API</title>
    <script
      src="https://www.w3.org/Tools/respec/respec-w3c"
      class="remove"
      async
    ></script>
    <script class="remove">
      var respecConfig = {
        specStatus: "ED",
        editors: [{ name: "Your Name", url: "https://your-site.example/" }],
        github: "some-org/mySpec",
        shortName: "my-api",
        xref: "web-platform",
        group: "my-working-group",
      };
    </script>
  </head>
  <body>
    <section id="abstract">
      <p>This spec defines the My API.</p>
    </section>
    <section id="sotd"></section>
    <section class="informative">
      <h2>Introduction</h2>
      <p>Some introductory text.</p>
      <aside class="note" title="A note">
        <p>Notes look like this.</p>
      </aside>
    </section>
    <section data-dfn-for="Foo">
      <h2>The <code>Foo</code> interface</h2>
      <pre class="idl">
        [Exposed=Window]
        interface Foo {
          attribute DOMString bar;
          undefined doTheFoo();
        };
      </pre>
      <p>The <dfn>Foo</dfn> interface represents a {{Foo}}.</p>
      <p>The <dfn>doTheFoo()</dfn> method does the foo. Call it via {{Foo/doTheFoo()}}.</p>
      <ol class="algorithm">
        <li>Let |result:DOMString| be a new string.</li>
        <li>Return |result|.</li>
      </ol>
    </section>
    <section id="conformance"></section>
  </body>
</html>

Preview it: Open the file via a local HTTP server — not file:// (browsers block fetches from file://):

# Any of these work:
npx serve .
python3 -m http.server

Then open http://localhost:PORT/your-spec.html.

1.2 Including ReSpec📝 Edit

Add these two <script> elements to the <head>. The class="remove" ensures they are stripped from the exported static HTML.

Example 2: Including ReSpec
<script
  src="https://www.w3.org/Tools/respec/respec-w3c"
  class="remove"
  async
></script>
<script class="remove">
  // var is required — ReSpec reads this as window.respecConfig
  // (const/let are block-scoped and not visible to the ReSpec bundle)
  var respecConfig = {
    // configuration options
  };
</script>
Note

Note: var is required — ReSpec reads this as window.respecConfig. const or let would not be visible to the ReSpec bundle.

ReSpec is continuously updated. Loading it from w3.org/Tools/respec/ means you automatically get the latest bug fixes and features.

1.3 Configuring ReSpec📝 Edit

All configuration options are documented in this reference. The minimum required options are specStatus and editors. For W3C working group documents, also set group.

Example 3: Minimum configuration
var respecConfig = {
  specStatus: "ED",
  editors: [{ name: "Your Name", url: "https://your-site.example/" }],
};

Configuration can also be overridden via URL query params — useful for generating snapshots without editing the source: index.html?specStatus=WD&publishDate=2025-06-01.

1.4 Document structure📝 Edit

ReSpec documents are HTML. They use standard HTML structural elements with a few conventions.

1.4.1 Title📝 Edit

Set the document title using the <title> element. ReSpec uses it to generate the <h1> heading.

Example 4: Setting the title
<title>Payment Request API</title>

If you need markup in the title (e.g., <code>), use <h1 id="title"> instead. See <h1 id="title">.

1.4.2 Subtitle📝 Edit

Add a subtitle either in config or as markup:

Example 5: Subtitle in config
var respecConfig = {
  subtitle: "Level 2",
};
Example 6: Subtitle in markup
<h2 id="subtitle">Level 2</h2>

1.4.3 Editors and authors📝 Edit

Example 7: Editors and authors
var respecConfig = {
  editors: [
    {
      name: "Robin Berjon",
      url: "https://berjon.com/",
      company: "W3C",
      companyURL: "https://w3c.org/",
      note: "until 2022",
    },
  ],
  authors: [
    {
      name: "Ada Lovelace",
      company: "Aristocracy",
      retiredDate: "1852-11-27",
    },
  ],
};

See person for all available fields.

1.4.4 Sections📝 Edit

Wrap content in <section> elements. ReSpec handles numbering, IDs, and ToC entries automatically.

Example 8: Sections and sub-sections
<section>
  <h2>Concepts</h2>
  <p>Some text.</p>
  <section class="informative">
    <h3>Background</h3>
    <p>Non-normative background text.</p>
  </section>
</section>

Empty links to a section's ID auto-fill with "§ N.N Title":

Example 9: Auto-linking to a section
<p>As described in <a href="#concepts"></a>...</p>
<!-- Renders: As described in § 2 Concepts... -->

Section classes: informative, appendix, notoc.

1.4.5 Table of Contents📝 Edit

Generated automatically after the SotD section. Control depth with maxTocLevel. Suppress with noTOC: true.

1.4.6 Figures📝 Edit

Example 10: Figure with auto-numbering
<figure id="fig-overview">
  <img src="overview.svg" alt="System overview diagram" />
  <figcaption>System overview.</figcaption>
</figure>

<p>See <a href="#fig-overview"></a> for the system overview.</p>
<!-- Renders: See Figure 1 for... -->

Generate a Table of Figures with <section id="tof">.

1.4.7 Examples, notes, and issues📝 Edit

Example 11: Common annotation boxes
<aside class="example" title="Using the API">
  <pre class="js">
    const result = await navigator.credentials.get();
  </pre>
</aside>

<div class="note">
  <p>Implementations should handle the error case.</p>
</div>

<p class="issue" data-number="42">
  <!-- Content of GitHub issue #42 is embedded automatically -->
</p>

1.4.8 Syntax highlighting📝 Edit

Code inside <pre> is automatically syntax-highlighted using highlight.js. Specify the language with a class:

Example 12: Code with explicit language
<pre class="js">const x = 1;</pre>
<pre class="css">.widget { color: red; }</pre>
<pre class="webidl">interface Foo {};</pre>

Use class="nohighlight" to disable. Use class="nolinks" to prevent URLs from becoming hyperlinks.

1.4.9 External includes📝 Edit

Example 13: Including external content
<section data-include="sections/api.html"></section>
<section data-include="sections/intro.md"
         data-include-format="markdown"></section>

Requires HTTPfile:// URLs will fail due to browser CORS restrictions. See data-include.

1.4.10 Conformance📝 Edit

Example 14: Conformance section
<section id="conformance">
  <!-- RFC 2119 boilerplate added automatically -->
  <p>Additional conformance text here.</p>
</section>

Required for specs with normative requirements. Adds RFC 2119 keyword definitions (MUST, SHOULD, MAY, etc.).

1.4.11 Abbreviations📝 Edit

Example 15: Abbreviations
<p>The <abbr title="World Wide Web Consortium">W3C</abbr> develops web standards.</p>
<!-- All subsequent occurrences of "W3C" are automatically wrapped in <abbr> -->

Or use data-abbr on a <dfn> to auto-generate abbreviations.

1.5 Definitions and linking📝 Edit

1.5.1 Define a term📝 Edit

Example 16: Defining a term
<p>The <dfn>fetch</dfn> algorithm retrieves a resource.</p>

1.5.3 Automatic pluralization📝 Edit

Example 18: Automatic plurals
<dfn>request</dfn>

<!-- All of these link correctly: -->
<a>request</a>
<a>requests</a>
[=request=]
[=requests=]

1.5.4 Alternative terms and aliases📝 Edit

Example 19: Multiple linking terms
<dfn data-lt="user agent|browser">user agent</dfn>

<!-- All link to the same definition: -->
[=user agent=]  [=browser=]

See data-lt.

1.5.5 Referencing terms from other specifications📝 Edit

Enable xref and write terms naturally — ReSpec finds them automatically:

Example 20: Enable xref
var respecConfig = {
  xref: "web-platform", // includes HTML, Infra, URL, WebIDL, DOM, Fetch
};
Example 21: Linking to external terms
<p>
  [=Queue a task=] to [=fire an event=] named "load"
  at the {{Window}} object.
</p>

Browse available terms at respec.org/xref.

1.5.6 Linking shorthands📝 Edit

Syntax Links to
[=term=] Concept or abstract term
{{Interface}} WebIDL interface
{{Interface/member}} WebIDL member
[^element^] HTML/SVG element
[[SPEC]] Informative bibliography reference
[[!SPEC]] Normative bibliography reference
[[[#section-id]]] Section in this document
[[[SPEC#section-id]]] Section in another spec

See the Shorthands Guide for full syntax.

1.6 References📝 Edit

Example 22: Bibliography references
The [^link^] element is defined in [[HTML]].
This MUST NOT be done per [[!RFC2119]].

ReSpec auto-generates a References section from all [[SPEC]] citations. Spec IDs come from Specref — which includes most W3C, WHATWG, ECMA, and IETF documents.

For a non-normative reference in a normative section, use [[?SPEC]].

To add a missing reference, contribute it to Specref or use localBiblio.

1.6.1 Normative vs. informative references📝 Edit

ReSpec infers from context: references in informative sections, notes, examples, or figures become informative automatically. References in normative sections are normative.

1.7 W3C documents📝 Edit

1.7.1 Working group📝 Edit

Example 23: Associate with a Working Group
var respecConfig = {
  group: "webapps", // see respec.org/w3c/groups/ for shortnames
};

group configures patent policy, group homepage, and mailing list automatically. It replaces the old wg, wgId, wgURI, wgPatentURI, and wgPublicList options.

1.7.2 Specification status📝 Edit

specStatus sets the document maturity level. Common values:

Value Description
"ED" Editor's Draft (default — for active development)
"WD" Working Draft
"CR" Candidate Recommendation
"REC" Recommendation
"CG-DRAFT" Community Group Draft

See specStatus for the full list.

1.7.3 Publishing to W3C TR/📝 Edit

For TR/ publication:

Example 24: Working Draft for TR/ publication
var respecConfig = {
  specStatus: "WD",
  publishDate: "2025-06-15",
  previousPublishDate: "2024-12-01",
  previousMaturity: "FPWD",
  group: "webapps",
  shortName: "my-api",
};

Export to static HTML first (ReSpec pill → Save as HTML), then submit via Echidna or the W3C publication tools.

1.8 WebIDL Guide📝 Edit

To specify an interface using WebIDL, you define a <pre class="idl"> block.

Example 25: Declaring a WebIDL block
<pre class="idl">
interface Request {
  readonly attribute ByteString method;
  readonly attribute USVString url;
};
</pre>

Ideal linking setup📝 Edit

The recommended pattern is a <section data-dfn-for="InterfaceName"> that groups the IDL block with prose definitions for each member:

Example 26: WebIDL definitions and linking
<section data-dfn-for="Fetch">
  <h2>The <code>Fetch</code> interface</h2>
  <pre class="idl">
  [Exposed=Window]
  interface Fetch {
    constructor(USVString url);
    readonly attribute USVString url;
    undefined send();
  };
  </pre>
  <section>
    <h2>Constructors</h2>
    <p>The <dfn constructor for="Fetch">constructor(url)</dfn> steps are:</p>
    <ol class="algorithm">
      <li>Set [=this=]'s {{Fetch/url}} to |url|.</li>
    </ol>
  </section>
  <section>
    <h2>Attributes</h2>
    <p>The <dfn attribute>url</dfn> attribute steps are to return [=this=]'s url.</p>
  </section>
  <section>
    <h2>Methods</h2>
    <p>The <dfn method>send()</dfn> method steps are:</p>
    <ol class="algorithm">
      <li>...</li>
    </ol>
  </section>
</section>

Using data-dfn-for📝 Edit

data-dfn-for on a <section> sets the default interface context for all <dfn> elements within it. This saves repeating the interface name on every definition:

Example 27: Using data-dfn-for
<section data-dfn-for="Request">
  <p>The <dfn>url</dfn> attribute of {{Request}}.</p>
  <p>The <dfn>clone()</dfn> method.</p>
  <!-- Both dfns are automatically "for Request" -->
</section>

Without data-dfn-for, use explicit for= attributes on individual <dfn> elements.

Constructors📝 Edit

Define constructors with <dfn constructor for="InterfaceName">:

Example 28: Constructor definition
<p>The <dfn constructor for="Widget">constructor(name, options)</dfn> steps are:</p>
<ol class="algorithm">
  <li>Let |w:Widget| be a new {{Widget}} object.</li>
  <li>Set |w|'s {{Widget/name}} to |name|.</li>
  <li>Return |w|.</li>
</ol>

Link to the constructor from prose: {{Widget/constructor(name, options)}}.

Enum values defined in the IDL block are automatically linked. To add prose descriptions, define them explicitly using data-dfn-type="enum-value" and data-dfn-for:

Example 29: Prose definitions for enum values
<pre class="idl">
enum RequestMode { "navigate", "cors", "no-cors", "same-origin" };
</pre>

<p>The <dfn data-dfn-type="enum-value" data-dfn-for="RequestMode">"cors"</dfn>
mode means cross-origin requests are sent with CORS headers.</p>

<p>The <dfn data-dfn-type="enum-value" data-dfn-for="RequestMode">"navigate"</dfn>
mode is used for top-level navigation.</p>

Link to enum values in prose: {{RequestMode/"cors"}}.

Dictionaries📝 Edit

Dictionary members defined in IDL are automatically linked. Reference them in prose as {{DictionaryName/memberName}}:

Example 30: Dictionary member linking
<pre class="idl">
dictionary RequestInit {
  ByteString method = "GET";
  boolean keepalive = false;
};
</pre>

<p>If |init|'s {{RequestInit/method}} is not a [=method=], throw a {{TypeError}}.</p>

Multiple interfaces with same attributes/methods📝 Edit

If two interfaces share attribute or method names, use data-dfn-for to distinguish them:

Example 31: Disambiguating same-named members
<section data-dfn-for="Request">
  <p>The <dfn>url</dfn> attribute of {{Request}}.</p>
</section>

<section data-dfn-for="Response">
  <p>The <dfn>url</dfn> attribute of {{Response}}.</p>
</section>

Dfn types for IDL members📝 Edit

When defining IDL members as prose <dfn> elements, you can omit data-dfn-type when data-dfn-for is set on the containing section — ReSpec infers the type from the IDL. For explicit control:

Pattern Type inferred
<dfn attribute>url</dfn> attribute
<dfn method>send()</dfn> method
<dfn constructor for="Foo">constructor()</dfn> constructor
<dfn data-dfn-type="dict-member">method</dfn> dict-member
  • The <pre class="idl"> block is syntax-highlighted and validated by ReSpec
  • IDL terms are automatically added to the terms index and IDL index
  • Use class="exclude" on a <pre class="idl"> to keep it out of the IDL index: <pre class="idl exclude">
  • See data-dfn-type for the full list of definition types

2. Creating Static Snapshots📝 Edit

Open the ReSpec UI and select "Export...".

Figure 1 Screen shot of ReSpec UI

Select the format to export as.

Figure 2 ReSpec's supports various export formats

2.1 Using command line📝 Edit

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
Note

3. Shorthands Cheat Sheet📝 Edit

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

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.

3.1 WebIDL📝 Edit

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.

Examples📝 Edit

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"}}

Aliasing methods📝 Edit

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()

3.2 Concepts📝 Edit

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.

Linking to concepts📝 Edit

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:

Example 32: Linking to concepts with xref and shorthands.
<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.

Plural Forms📝 Edit

ReSpec supports automatically linking to plural forms for simple nouns. Thus, [=fruits=] links to the singular concept of fruit, even across specs.

Aliasing concepts📝 Edit

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 🙇‍♂️).

Examples📝 Edit

Type Syntax Examples
Concept [=concept=] [=queue a task=]
Aliased concept [=concept|some alias=]
[=convoluted thing|simpler thing=]
[=queue a task|task queuing=]

Scoped concepts📝 Edit

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:

Example 33: Concepts scoped to other concepts.
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.

Examples📝 Edit

Type Syntax Examples
Concept for thing [=concept/sub concept=] [=list/for each=]
[=map/for each=]
[=Document/visible=]

3.3 Variables in algorithms📝 Edit

The syntax is |name|, where name is the name of the variable.

Example 34: Shorthand syntax for declaring a variable 'value'.
Let |value| be the {{DOMString}} "hello". ... If |value| is not "hello", then
do…

Giving variables data types📝 Edit

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).

Examples📝 Edit

Type Syntax Examples
Variable |variable| |value|
Variable with a data type |variable:dataType| |value:DOMString|

3.4 HTML/SVG Elements and attributes📝 Edit

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.

Examples📝 Edit

Type Syntax Examples
Element [^element^] [^iframe^]
Element with Content Attribute [^element/contentAttribute^] [^iframe/allow^]
Note

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}}.

3.5 Referencing other specifications📝 Edit

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.

Examples📝 Edit

Type Syntax Examples
Normal Reference [[SHORTNAME]] [[HTML]]
Expanded Reference [[[SHORTNAME]]] [[[FULLSCREEN]]], [[[fullscreen API]]]
are expanded and rendered as
Full Screen API
Cross-spec section link [[[SHORTNAME#id]]] [[[fetch#data-fetch]]]
renders as a link to that section with the spec title as text
Informative spec [[?SHORTNAME]] Payments can be useful [[?PAYMENT-REQUEST]].
Escaped reference [[\anything]] This is not a reference. It is [[\something else]].
Inner-document expansion [[[#fragment]]] See [[[#installability-signals]]]
is expanded and rendered as
See § 2.6 Installability signals.
Multi-page reference [[SHORTNAME/page#fragment]] [[SOMESPEC/foo.html#bar]]
(Not recommended, use only if you really need it!)

4. Using Markdown with ReSpec📝 Edit

ReSpec supports GitHub Flavored Markdown (GFM) for writing specification content.

Enable globally📝 Edit

Example 35: Enable Markdown for the whole document
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.

Enable for a single section📝 Edit

Example 36: Markdown for one included section
<section data-include="my-section.md"
         data-include-format="markdown"></section>

Automatic sectioning📝 Edit

Markdown headings create nested <section> elements automatically:

Example 37: Headings become sections
## Introduction

Some text.

### Background

More text.

Custom heading IDs📝 Edit

Example 38: Custom heading ID
## My Heading {#my-custom-id}

Figures📝 Edit

An image with a title becomes a <figure> with <figcaption>:

Example 39: Markdown figure
![alt text](diagram.svg "Caption for the figure")

Code blocks📝 Edit

Use triple-backtick fences with a language hint:

Example 40: Syntax-highlighted code block
```js
async function fetchData() {
  return await fetch("/api/data.json");
}
```

For WebIDL blocks:

Example 41: WebIDL block in Markdown
```webidl
[Exposed=Window]
interface Example {
  undefined doThing();
};
```

Mixing HTML and Markdown📝 Edit

HTML elements and Markdown can be mixed, but require a blank line between the tag and the content:

Example 42: HTML and Markdown mixed
<div class="note">

This is **Markdown** inside an HTML element.

</div>

5. Configuration Options

5.2 authors📝 Edit

Type: Person[] Default: []

An array of person objects describing the document's authors. Shown below the editors in the document header.

Basic usage📝 Edit

Example 44: List of authors
var respecConfig = {
  authors: [
    {
      name: "Alice Smith",
      company: "Example Corp",
      companyURL: "https://example.org/",
      w3cid: 12345,
    },
  ],
};
  • In most cases, editors is preferred over authors for W3C specifications
  • Use authors for major contributors who are not editors, or when the document follows a format that distinguishes authors from editors
  • See person for full documentation of person object fields

5.3 caniuse📝 Edit

Type: string | CaniuseOptions Default: undefined

Adds a browser support table to the document header, sourced from caniuse.com.

Basic usage📝 Edit

Example 45: Browser support table for payment-request
var respecConfig = {
  caniuse: "payment-request",
};

With options📝 Edit

Example 46: Show only specific browsers
var respecConfig = {
  caniuse: {
    feature: "payment-request",
    browsers: ["chrome", "firefox", "safari", "edge"],
  },
};

Options📝 Edit

Option Type Default Description
feature string required caniuse.com feature key (the slug from the URL)
browsers string[] all major Browser IDs to include in the table
removeOnSave boolean true Strip the widget when saving as HTML; replace with a link to caniuse.com
apiURL string caniuse data on respec.org Override the caniuse data endpoint — advanced use, e.g. self-hosted data

Supported browser IDs📝 Edit

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
  • The caniuse widget requires JavaScript — in saved/exported HTML it is replaced by a plain link to caniuse.com
  • The feature key is the slug from the caniuse.com URL: https://caniuse.com/FEATURE-KEY
  • wf-* prefixed features (Baseline/web-features) are not yet supported — they come from a different data source
  • To find the right feature key, browse caniuse.com and copy the URL slug

5.4 edDraftURI📝 Edit

Type: 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.

Basic usage📝 Edit

Example 47: Set the Editor's Draft URL
var respecConfig = {
  specStatus: "ED",
  edDraftURI: "https://w3c.github.io/payment-request/",
};
  • When github is set, edDraftURI is automatically derived from the repo — you usually don't need to set it manually
  • Set to null to suppress the link: edDraftURI: null
  • For published W3C documents, editors' drafts are typically hosted on GitHub Pages (https://w3c.github.io/short-name/)

5.5 editors📝 Edit

Type: Person[] Default: []

An array of person objects describing the editors of the document. At least one editor is required for most W3C documents.

Basic usage📝 Edit

Example 48: List of editors
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,
    },
  ],
};

Person object fields📝 Edit

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
  • See person for full documentation of all person object fields and the extras format
  • To credit former editors, use formerEditors, or set retiredDate to keep them listed inline
  • For non-editor contributors, use authors

5.6 format📝 Edit

Type: "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.

Basic usage📝 Edit

Example 49: Enable Markdown for the whole document
var respecConfig = {
  format: "markdown",
};
  • To use Markdown for only specific included sections, use data-include-format="markdown" instead of setting this globally
  • When using format: "markdown", keep all text flushed to the left — Markdown is whitespace-sensitive
  • See the Markdown guide for detailed usage, examples, and known limitations

5.7 formerEditors📝 Edit

Type: Person[] Default: []

An array of person objects listing past editors of the document. Shown below the current editors list.

Basic usage📝 Edit

Example 50: List former editors
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 },
  ],
};
  • Use formerEditors to keep a clean current editors list while acknowledging past contributors
  • Alternatively, add a retiredDate to a person in editors to show them inline as "until [date]"
  • See person for full documentation of person object fields

5.8 github📝 Edit

Type: 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.

Basic usage📝 Edit

Example 51: Set GitHub repository (shortest form)
var respecConfig = {
  github: "w3c/payment-request",
};
Example 52: Set GitHub repository as full URL
var respecConfig = {
  github: "https://github.com/w3c/payment-request",
};

With options📝 Edit

Example 53: Non-default branch
var respecConfig = {
  github: {
    repoURL: "https://github.com/w3c/payment-request",
    branch: "main",
  },
};
Example 54: Monorepo — filtered PRs and commit history
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/",
  },
};

Options📝 Edit

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)
  • Setting github auto-populates edDraftURI — no need to set it separately
  • For monorepos where multiple specs share one repository, use pullsURL and commitHistoryURL to filter to your spec's files

5.9 highlightVars📝 Edit

Type: boolean Default: true

Enables click-to-highlight for <var> elements in algorithms. When a reader clicks a variable, all instances of that variable within the same section are highlighted, making it easier to trace variable usage through long algorithms.

Basic usage📝 Edit

Example 55: Disable variable highlighting
var respecConfig = {
  highlightVars: false,
};
  • Variables must be marked up with <var> elements: Let <var>request</var> be a new request.
  • Highlighting is scoped to the nearest enclosing .algorithm list or <section> — whichever is closest
  • Clicking multiple variables gives each a distinct highlight color (up to 7 colors)
  • The |variable| shorthand automatically generates <var> elements

5.10 isPreview📝 Edit

Type: 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.

Basic usage📝 Edit

Example 56: Mark document as a preview
var respecConfig = {
  isPreview: true,
};
  • Shows a large red "Preview" banner — intentionally attention-grabbing
  • Useful for PR preview deployments to avoid readers accidentally citing a draft-of-a-draft
  • Do not set in production specs

5.11 license📝 Edit

Type: string Default: "w3c-software-doc"

The copyright license for the document.

Basic usage📝 Edit

Example 57: Use the default W3C license (usually no need to set this)
var respecConfig = {
  // w3c-software-doc is already the default for W3C documents
};
Example 58: Set a specific license
var respecConfig = {
  license: "cc0",
};

Valid values📝 Edit

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.
  • For most W3C specifications, the default is correct — no need to set license explicitly
  • cc0 is intended for documents heading to the WHATWG; W3C does not support it

5.12 lint📝 Edit

Type: 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.

5.12.1 Basic usage — enable all rules📝 Edit

Example 59: Linting is on by default
var respecConfig = {
  // lint: true is the default — no need to set it explicitly
};

5.12.2 Disable all linting📝 Edit

Example 60: Disable linter entirely
var respecConfig = {
  lint: false,
};

5.12.3 Enable or disable individual rules📝 Edit

Example 61: Configure individual lint rules
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
  },
};

5.12.4 Available rules📝 Edit

Rule Default What it checks
a11y false Accessibility issues
check-charset false Missing or duplicate <meta charset="utf-8">
check-internal-slots false Internal slot references missing the . separator (|obj|.[[slot]])
check-punctuation false Missing punctuation at end of paragraphs
informative-dfn false Definitions in informative sections
local-refs-exist true Local #fragment links that don't resolve
no-captionless-tables true Tables without a <caption>
no-dfn-in-abstract false <dfn> elements in abstract, SotD, or other unnumbered sections
no-headingless-sections true Sections without a heading
no-http-props true Non-HTTPS URLs in config
no-unused-dfns false Defined terms never referenced
no-unused-vars false WebIDL variables never used
privsec-section false Missing Privacy and Security Considerations section
wpt-tests-exist false data-tests attributes pointing to non-existent WPT tests

5.12.5 Suppress a single violation inline📝 Edit

Use data-lint-ignore to suppress a specific warning on an element:

Example 62: Suppress a lint warning on one element
<table data-lint-ignore="no-captionless-tables">
  <tr><td>data</td></tr>
</table>

5.12.6 Notes📝 Edit

  • Rule severity can be true (error), "warn" (warning), or false (disabled)
  • Linting errors appear as red banners in the document header; warnings appear as yellow

5.12.7 a11y linting rule📝 Edit

Default: false

Runs accessibility checks using axe-core. Reports violations as ReSpec warnings, highlighting the offending elements in the document.

How to enable📝 Edit
Example 63: Run all default accessibility rules
var respecConfig = {
  lint: {
    a11y: true,
  },
};
Example 64: Run only specific rules
var respecConfig = {
  lint: {
    a11y: {
      runOnly: ["image-alt", "link-name"],
    },
  },
};
Example 65: Enable a slow rule; disable another
var respecConfig = {
  lint: {
    a11y: {
      rules: {
        "color-contrast": { enabled: true },  // slow — disabled by default
        "image-alt": { enabled: false },
      },
    },
  },
};
Rules disabled by default📝 Edit

These axe-core rules run if you enable a11y: true, except the following, which are disabled because they are slow or produce false positives on spec documents:

Rule Reason disabled
color-contrast Too slow — enable explicitly when needed
landmark-one-main Spec pages often lack <main>; would mark entire page as errored
landmark-unique Causes false positives in spec document structure
region Similar false-positive issue with spec layout

All other axe-core default rules run. For the full list, see axe-core rule descriptions.

Quick enable via URL📝 Edit

Add ?a11y=true to any spec URL to enable all default rules temporarily, without changing config.

  • Violations appear as yellow warnings in the ReSpec pill counter; click to see the offending elements highlighted
  • Running on hosted documents (GitHub Pages, W3C servers) may slow load time — enable selectively
  • See axe options documentation for the full configuration API
How to disable📝 Edit
Example 66: Disable a11y checks
var respecConfig = {
  lint: { a11y: false },
};

5.12.8 check-punctuation linting rule📝 Edit

Default: false

Warns when a <p> element does not end with punctuation. Helps maintain consistent typographic quality in specifications.

Example violation📝 Edit
<!-- BAD: paragraph ends without punctuation -->
<p>The widget is initialized during construction</p>
How to fix📝 Edit

Add a period (or other appropriate punctuation) at the end of the paragraph.

How to enable📝 Edit
Example 67: Enable check-punctuation
var respecConfig = {
  lint: {
    "check-punctuation": true,
  },
};
How to disable📝 Edit
Example 68: Disable this rule
var respecConfig = {
  lint: { "check-punctuation": false },
};

5.12.9 informative-dfn linting rule📝 Edit

Default: 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.

Example violation📝 Edit
<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>
How to fix📝 Edit

Either:

  1. Move the <dfn> to a normative section
  2. Use a normative proxy: <dfn data-cite="spec#fancy-algorithm">fancy algorithm</dfn>
  3. Add class="lint-ignore" to the specific link to suppress the warning
How to enable📝 Edit
Example 69: Enable informative-dfn rule
var respecConfig = {
  lint: { "informative-dfn": true },
};

5.12.10 local-refs-exist linting rule📝 Edit

Default: true

Warns when an href="#fragment" link points to an anchor that doesn't exist in the document.

Example violation📝 Edit
<section id="foo">...</section>

<!-- BAD: #bar doesn't exist in the document -->
<a href="#bar">link</a>
How to fix📝 Edit

Either fix the href to point to an existing ID, or add the missing ID to the target element.

How to disable📝 Edit
Example 70: Disable this rule
var respecConfig = {
  lint: { "local-refs-exist": false },
};

5.12.11 no-captionless-tables linting rule📝 Edit

Default: true

Warns when a numbered <table> (with class="numbered") does not have a <caption> as its first child.

Example violation📝 Edit
<!-- 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>
How to fix📝 Edit
<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>
How to disable📝 Edit
Example 71: Disable this rule
var respecConfig = {
  lint: { "no-captionless-tables": false },
};
  • Only applies to <table class="numbered"> — unnumbered tables are not checked
  • The <caption> must be the first child of <table>
  • Captions are required for accessibility and for the auto-generated Table of Tables

5.12.12 no-headingless-sections linting rule📝 Edit

Default: true

Warns when a <section> element does not begin with a heading element (<h2><h6>).

Example violation📝 Edit
<!-- BAD: no heading -->
<section id="intro">
  <p>Content without a heading.</p>
</section>
How to fix📝 Edit
<section id="intro">
  <h2>Introduction</h2>
  <p>Content with a heading.</p>
</section>
How to disable📝 Edit
Example 72: Disable this rule
var respecConfig = {
  lint: { "no-headingless-sections": false },
};
  • Sections without headings are inaccessible — screen readers and ToC generation depend on headings
  • The one exception is the <body> element itself, which is not required to start with a heading

5.12.13 no-http-props linting rule📝 Edit

Default: true

Warns when any URL in respecConfig uses http:// instead of https://. W3C publication rules require HTTPS.

Example violation📝 Edit
var respecConfig = {
  // BAD: http:// not https://
  implementationReportURI: "http://example.org/report.html",
};
How to fix📝 Edit

Change http:// to https:// for the flagged URL.

How to disable📝 Edit
Example 73: Disable this rule
var respecConfig = {
  lint: { "no-http-props": false },
};

5.12.14 no-unused-dfns linting rule📝 Edit

Default: false

Warns when a definition (<dfn>) is never referenced anywhere in the document and is not exported.

How to enable📝 Edit
Example 74: Enable no-unused-dfns rule
var respecConfig = {
  lint: {
    "no-unused-dfns": true,
  },
};
Example violation📝 Edit
<!-- Defined but never linked to anywhere in the document: -->
<dfn>orphaned concept</dfn>
How to fix📝 Edit

Choose one:

  1. Link to it somewhere in the document: [=orphaned concept=]
  2. Export it so other specs can use it: <dfn class="export">orphaned concept</dfn>
  3. Remove the <dfn> if the term is no longer needed
  4. Use a plain element if you want the text styled as a definition but don't need linking: <span class="dfn-paneled">term</span>
How to disable📝 Edit
Example 75: Disable this rule
var respecConfig = {
  lint: { "no-unused-dfns": false },
};

5.12.15 no-unused-vars linting rule📝 Edit

Default: 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.

Example violation📝 Edit
Example 76: Used and unused algorithm variables
<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>
How to enable📝 Edit
Example 77: Enable no-unused-vars rule
var respecConfig = {
  lint: { "no-unused-vars": true },
};
Suppress for one variable📝 Edit
Example 78: Suppress warning for a specific variable
<var data-ignore-unused>someVar</var>
  • Only applies inside <ol class="algorithm"> sections
  • The first occurrence of a |variable| is treated as its definition
  • The |variable| shorthand does not support data-ignore-unused — use <var data-ignore-unused> explicitly

5.12.16 privsec-section linting rule📝 Edit

Default: 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.

How to add the section📝 Edit
Example 79: Privacy and Security Considerations section
<section>
  <h2>Privacy and Security Considerations</h2>
  <p>This specification introduces no new privacy or security concerns
  beyond those described in [[FETCH]].</p>
</section>
How to enable📝 Edit
Example 80: Enable privsec-section rule
var respecConfig = {
  lint: { "privsec-section": true },
};
How to disable📝 Edit
Example 81: Disable privsec-section rule
var respecConfig = {
  lint: { "privsec-section": false },
};
  • The section should have an <h2> titled "Privacy and Security Considerations" or similar
  • Even for low-risk APIs, a brief section explaining why there are no concerns is good practice
  • See the Security and Privacy Questionnaire for guidance on what to include

5.12.17 wpt-tests-exist linting rule📝 Edit

Default: false

Warns when a data-tests attribute references a WPT test file that doesn't exist in the web-platform-tests repository.

How to enable📝 Edit
Example 82: Enable wpt-tests-exist
var respecConfig = {
  testSuiteURI: "https://github.com/web-platform-tests/wpt/tree/HEAD/payment-request/",
  lint: {
    "wpt-tests-exist": true,
  },
};
Example violation📝 Edit
<!-- BAD: nonexistent-test.html doesn't exist in WPT -->
<p data-tests="valid-test.html,nonexistent-test.html"></p>
How to fix📝 Edit

Either correct the test path or remove the reference to the non-existent test.

  • Requires testSuiteURI to be set — ReSpec uses it to determine the WPT base path
  • Checks against the live WPT repository on GitHub
  • See data-tests for how to annotate spec sections with test references

5.13 localBiblio📝 Edit

Type: Object Default: {}

Adds custom bibliography entries that are not in the SpecRef database, or overrides existing entries for this document.

Basic usage📝 Edit

Example 83: Add a custom bibliography entry
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).

Entry fields📝 Edit

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
  • Prefer contributing to SpecReflocalBiblio should be a last resort. Entries in SpecRef benefit all specs, not just yours.
  • To override a SpecRef entry for this document only, use the same key with your custom values
  • Keys are case-insensitive in citations ([[fetch]] and [[FETCH]] refer to the same entry)

5.14 logos📝 Edit

Type: 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.

Basic usage📝 Edit

Example 85: Multiple logos (W3C + partner)
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,
    },
  ],
};

Logo object fields📝 Edit

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
  • Setting logos replaces the default W3C logo — include the W3C logo explicitly if you need it alongside your custom logo
  • SVG logos are recommended for crisp rendering at any size

5.15 maxTocLevel📝 Edit

Type: 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.

Basic usage📝 Edit

Example 86: Limit ToC to 2 levels deep
var respecConfig = {
  maxTocLevel: 2,
};
  • maxTocLevel: 0 (default) includes all heading levels in the ToC
  • Use data-max-toc="N" on individual sections to override for that subtree
  • For very large specs, limiting ToC depth improves readability

5.16 mdn📝 Edit

Type: 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.

Basic usage📝 Edit

Example 87: Enable MDN annotations using shortName as key
var respecConfig = {
  shortName: "payment-request",
  mdn: true,
};
Example 88: Enable MDN annotations with explicit key
var respecConfig = {
  mdn: "payment-request",
};

With options📝 Edit

Example 89: Custom MDN data source
var respecConfig = {
  mdn: {
    key: "payment-request",
    maxAge: 3600000, // 1 hour cache
  },
};

Options📝 Edit

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)
  • MDN annotations are collapsed by default — click to expand a panel showing browser support and a link to MDN
  • Each panel shows an engine support summary (✅ all engines / 🚫 limited) and per-browser version data
  • Annotations appear next to relevant section IDs that match MDN's data — not all sections will have annotations
  • To find the right key, look up your spec URL in SPECMAP.json

5.17 modificationDate📝 Edit

Type: 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.

Basic usage📝 Edit

Example 90: Document with an in-place modification
var respecConfig = {
  publishDate: "2020-03-30",
  modificationDate: "2020-04-13",
};
  • Only used when making an in-place editorial correction to a published document (no new publication date)
  • Format must be "YYYY-MM-DD"
  • For substantive changes, use a new publishDate instead

5.18 monetization📝 Edit

Type: 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.

Basic usage📝 Edit

Example 91: Use your own payment pointer
var respecConfig = {
  monetization: "$wallet.example.com/my-wallet",
};
Example 92: Disable monetization entirely
var respecConfig = {
  monetization: false,
};
Example 93: Keep pointer in saved HTML
var respecConfig = {
  monetization: {
    paymentPointer: "$wallet.example.com/my-wallet",
    removeOnSave: false,
  },
};

Options📝 Edit

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
  • Web Monetization is an emerging payment standard for the web
  • Setting false disables monetization and removes the default ReSpec pointer

5.19 noTOC📝 Edit

Type: boolean Default: false

Suppresses generation of the table of contents.

Basic usage📝 Edit

Example 94: Disable table of contents
var respecConfig = {
  noTOC: true,
};
  • To exclude individual sections from the ToC rather than removing it entirely, add class="notoc" to the section — see notoc-class

5.21 pluralize📝 Edit

Type: 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.

Basic usage📝 Edit

Example 96: Pluralization is on by default
var respecConfig = {
  // pluralize: true is already the default for W3C specs
};

How it works📝 Edit

Example 97: Automatic plural forms
<dfn>user agent</dfn>

<!-- Both of these link correctly: -->
<a>user agent</a>
<a>user agents</a>
Example 98: Pluralization with data-lt
<dfn data-lt="pub">bar</dfn>

<!-- All of these link correctly: -->
<a>bar</a>  <a>bars</a>  <a>pub</a>

Opt out per definition📝 Edit

Example 99: Disable pluralization for one term
<dfn data-lt-no-plural>CSS</dfn>
<!-- "CSSs" will NOT be recognized as a link -->
  • Pluralization uses an English pluralization library — it handles irregular forms reasonably well but may miss edge cases
  • Plurals are only added for terms that are actually referenced — no overhead for unreferenced terms
  • Use data-lt-no-plural to suppress pluralization for acronyms, brand names, or terms where pluralization would be wrong
  • See also data-lt for manually defining alternative forms

5.22 postProcess📝 Edit

Type: Array<(config: Object, document: Document, utils: Object) => void | Promise<void>> Default: []

An array of functions that run after ReSpec has finished all processing. Use this to add custom sections, validate the final output, or modify generated markup.

Example 100: Add implementation status from an external source
async function addImplStatus(config, document) {
  const res = await fetch("https://api.example.org/impl-status.json");
  const status = await res.json();

  // Add a badge to each section that has implementation data
  for (const [id, data] of Object.entries(status)) {
    const section = document.getElementById(id);
    if (!section) continue;
    const badge = document.createElement("span");
    badge.className = "impl-badge";
    badge.textContent = `${data.implementations} implementations`;
    section.querySelector("h2, h3")?.append(" ", badge);
  }
}

var respecConfig = {
  postProcess: [addImplStatus],
};
Example 101: Validate output and log errors
function validateSpec(config, document) {
  // Check that all normative sections have at least one dfn or algorithm
  const normativeSections = document.querySelectorAll(
    "section:not(.informative):not(.appendix)"
  );
  for (const section of normativeSections) {
    if (!section.querySelector("dfn, ol.algorithm")) {
      console.warn("Section with no dfn or algorithm:", section.id);
    }
  }
}

var respecConfig = {
  postProcess: [validateSpec],
};

Function signature📝 Edit

Each function receives three arguments:

Argument Type Description
config Object The respecConfig object plus ReSpec internal state
document Document The fully processed ReSpec document
utils Object ReSpec utility functions
  • Functions run in order, awaiting async functions before proceeding
  • At this point: headings are numbered, ToC is built, dfn panels are generated, xrefs are resolved, boilerplate is inserted. You are working with the final output.
  • Changes appear in both the live preview and the saved HTML export
  • To be notified when ALL processing is complete (including postProcess), use document.respec.ready
  • For pre-processing before ReSpec starts, see preProcess

5.23 preProcess📝 Edit

Type: Array<(config: Object, document: Document, utils: Object) => void | Promise<void>> Default: []

An array of functions that run before ReSpec begins processing. Use this to fetch external data, inject content into the document, or perform setup that other processing steps depend on.

Example 102: Fetch external data before processing
async function loadTerms(config, document) {
  const res = await fetch("https://api.example.org/terms.json");
  const terms = await res.json();

  // Inject <dfn> elements so xref can resolve them
  const section = document.querySelector("#terminology");
  for (const { id, label } of terms) {
    const p = document.createElement("p");
    p.innerHTML = `The <dfn data-export id="${id}">${label}</dfn> is ...`;
    section.append(p);
  }
}

var respecConfig = {
  preProcess: [loadTerms],
};
Example 103: Inject a generated section
function addGeneratedSection(config, document) {
  const section = document.createElement("section");
  section.id = "build-info";
  section.innerHTML = `
    <h2>Build Information</h2>
    <p>Built by: <strong>${config.editors[0].name}</strong></p>
  `;
  document.body.insertAdjacentElement("beforeend", section);
}

var respecConfig = {
  preProcess: [addGeneratedSection],
};

Function signature📝 Edit

Each function receives three arguments:

Argument Type Description
config Object The respecConfig object plus ReSpec internal state
document Document The HTML document in its original, unprocessed form
utils Object ReSpec utility functions
  • Functions run in order, and ReSpec awaits each one before proceeding
  • async functions are fully supported
  • preProcess runs before any ReSpec transformation — the document is still in its original source form. Definitions, headings, and xrefs have not yet been processed.
  • For post-processing after ReSpec is done, see postProcess

5.24 publishDate📝 Edit

Type: 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.

Basic usage📝 Edit

Example 104: Set explicit publication date
var respecConfig = {
  publishDate: "2025-06-15",
};
  • Format must be "YYYY-MM-DD"
  • For "ED" status, omit this — ReSpec uses the browser's last-modified date, which is always current
  • For published documents ("WD", "CR", "REC", etc.), set this to the actual publication date
  • The browser's last-modified date can occasionally be wrong due to server timezone issues — if you see wrong dates on "ED" specs, set publishDate explicitly

5.25 shortName📝 Edit

Type: 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.

Basic usage📝 Edit

Example 105: Set the specification short name
var respecConfig = {
  shortName: "payment-request",
};
  • Must match exactly the short name registered with W3C for published documents
  • Used to construct: the TR URL, the Editor's Draft URL (when edDraftURI is not set), and the mdn annotation key (when mdn is true)
  • For Community Group reports, use the CG's assigned short name
  • Short names are typically lowercase with hyphens (e.g. "fetch", "web-animations", "css-color-5")

5.26 specStatus📝 Edit

Type: string Default: "ED"

The publication status of the document. Controls the document title, status boilerplate, and which sections are shown.

Basic usage📝 Edit

Example 106: Editor's Draft (active development)
var respecConfig = {
  specStatus: "ED",
};
Example 107: Working Draft (published on TR/)
var respecConfig = {
  specStatus: "WD",
  previousPublishDate: "2024-01-15",
  previousMaturity: "FPWD",
};

Valid values📝 Edit

W3C Recommendation Track📝 Edit
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
W3C Notes Track📝 Edit
Value Full name
"DNOTE" Group Note Draft
"NOTE" Group Note
"STMT" Statement
W3C Registry Track📝 Edit
Value Full name
"DRY" Registry Draft
"CRYD" Candidate Registry Draft
"CRY" Candidate Registry Snapshot
"RY" Registry
Community & Business Groups📝 Edit
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 development
  • Use noRecTrack if the document should not follow the Recommendation track
  • For "unofficial", content is auto-licensed under CC-BY v3.0; use license to change this
  • See W3C Standards and Draft document types for the normative definition of each document type

5.27 subjectPrefix📝 Edit

Type: string Default: undefined

Adds a prefix to mailing list feedback subjects. When set, feedback links in the document header will include this prefix in the mailto: subject line.

Basic usage📝 Edit

Example 108: Set mailing list subject prefix
var respecConfig = {
  subjectPrefix: "[payment-request]",
};
  • Include brackets if you want them (e.g. "[my-spec]" not "my-spec")
  • Only relevant when using a mailing list for feedback (via wgPublicList or similar)
  • With github configured, GitHub issues are the preferred feedback channel

5.28 subtitle📝 Edit

Type: string Default: ""

A subtitle shown below the document title in the header.

Basic usage📝 Edit

Example 109: Add a subtitle
var respecConfig = {
  subtitle: "Level 1",
};
  • For spec level numbers, prefer level which integrates with shortName and ToC numbering

5.29 testSuiteURI📝 Edit

Type: string Default: undefined

URL of the test suite for this specification. Shown in the document header as a "Test suite" link.

Basic usage📝 Edit

  • Required when using the wpt-tests-exist linting rule — ReSpec uses this URL to validate data-tests paths
  • Can be a WPT URL (https://wpt.fyi/...), GitHub URL, or any test suite URL
  • Use https://github.com/web-platform-tests/wpt/tree/HEAD/your-spec/ for the WPT GitHub tree view

5.30 xref📝 Edit

Type: 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.

Basic usage📝 Edit

Example 111: Enable xref with web-platform profile
var respecConfig = {
  xref: "web-platform",
};

Then write terms naturally — ReSpec links them automatically:

Example 112: Automatic term linking
<p>
  [=Queue a task=] to [=fire an event=] named "fetch"
  at the {{Window}} object.
</p>

How xref works📝 Edit

Understanding the pipeline helps when terms aren't found:

Your spec writes [=fetch=]
       ↓
ReSpec queries the xref service (respec.org/xref)
       ↓
Service looks up "fetch" in the WebRef database
       ↓
WebRef is populated by Reffy, which crawls published specs every 6 hours
       ↓
Reffy finds terms marked with <dfn data-export> in published specs
       ↓
Term found → generates <a href="https://fetch.spec.whatwg.org/#concept-fetch">fetch</a>
Term not found → ReSpec shows a red error banner

For a term to be findable via xref, ALL of these must be true:

  1. The defining spec is listed in browser-specs
  2. The defining spec is published (Editor's Drafts are crawled; unpublished local files are not)
  3. The <dfn> in the defining spec has data-export or class="export"
  4. Reffy has crawled it (within the last 6 hours for EDs; weekly for TR snapshots)

If a term isn't in the database, ask the defining spec's editors to add data-export. See data-export.

Configuration forms📝 Edit

Boolean📝 Edit
Example 113: Enable xref (minimal)
var respecConfig = {
  xref: true,
};
Profile name📝 Edit
Example 114: Use web-platform profile
var respecConfig = {
  xref: "web-platform",
};

The "web-platform" profile includes: HTML, INFRA, URL, WEBIDL, DOM, FETCH.

Array of spec shortnames📝 Edit
Example 115: Limit xref to specific specs
var respecConfig = {
  xref: ["FETCH", "DOM"],
};
Object (advanced)📝 Edit
Example 116: Profile + additional specs
var respecConfig = {
  xref: {
    profile: "web-platform",
    specs: ["PERMISSIONS", "SCREEN-WAKE-LOCK"],
  },
};

Options📝 Edit

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)

6. W3C Specific Configuration Options

6.1 additionalCopyrightHolders📝 Edit

Type: string Default: undefined

Adds an additional copyright holder alongside W3C in the document copyright notice. Used when publishing documents developed in cooperation with other standards organizations (e.g., IETF) or when the spec is jointly owned.

Basic usage📝 Edit

  • For W3C documents: appended to the standard W3C copyright notice ("Copyright © [year] W3C® and [holder]")
  • For "unofficial" documents: replaces the default CC license text entirely
  • The value is rendered as HTML — you can include links or special characters

6.2 alternateFormats📝 Edit

Type: Array<{ label: string, uri: string }> Default: []

Shows links to alternate formats of the specification (PDF, ePub, etc.) in the document header.

Basic usage📝 Edit

  • Each entry requires both label (display text) and uri (URL)
  • Links appear in the document header under "Also available in:"
  • You are responsible for generating and hosting the alternate format files — ReSpec only links to them

6.3 canonicalURI📝 Edit

Type: string | "edDraft" | "TR" Default: undefined

Sets the <link rel="canonical"> URL for the document, helping search engines identify the authoritative version.

Basic usage📝 Edit

Example 119: Point canonical to TR/ location
var respecConfig = {
  shortName: "payment-request",
  canonicalURI: "TR",
};
Example 120: Point canonical to Editor's Draft
var respecConfig = {
  canonicalURI: "edDraft",
};
Example 121: Explicit canonical URL
var respecConfig = {
  canonicalURI: "https://respec.org/docs/",
};

Keyword values📝 Edit

Value Generates
"TR" https://www.w3.org/TR/shortName/
"edDraft" The value of edDraftURI
  • Use "TR" for the published version to ensure search engines index the stable W3C TR/ URL rather than the Editor's Draft
  • Omit for documents where canonicalization isn't needed (e.g. unofficial drafts)

6.4 charterDisclosureURI📝 Edit

Type: string Default: undefined

URL to the patent disclosure section of the group charter. Required for Interest Group Notes — points to the W3C publication rules requirement for patent policy disclosure.

Basic usage📝 Edit

Example 122: Interest Group Note with charter disclosure
var respecConfig = {
  charterDisclosureURI: "https://www.w3.org/2019/06/me-ig-charter.html#patentpolicy",
};
  • Only relevant for Interest Group Notes — ignored for all other document types
  • Must point to the disclosure section in the group's charter document

6.5 copyrightStart📝 Edit

Type: number Default: year of publishDate

The first year of the copyright period. When a spec has been developed over multiple years, use this to show a copyright range (e.g., "Copyright © 2018–2025").

Basic usage📝 Edit

  • If copyrightStart equals the publishDate year, it has no effect (year range is suppressed)
  • Safe to always set — if it matches the publish year, ReSpec ignores it
  • Use the year the spec work first began, not when the first draft was published

6.6 crEnd📝 Edit

Type: 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.

Basic usage📝 Edit

Example 124: Candidate Recommendation with end date
var respecConfig = {
  specStatus: "CR",
  crEnd: "2025-09-01",
};
  • Required for "CR" and "CRD" — ReSpec will warn if missing
  • Also required for "PR" (alongside prEnd)
  • Format must be "YYYY-MM-DD"
  • This is the date the group commits to maintaining the document at its current maturity level until

6.7 doJsonLd📝 Edit

Type: boolean Default: false

Adds a <script type="application/ld+json"> element with schema.org metadata describing the document. Useful for search engine discoverability.

Basic usage📝 Edit

Example 125: Enable JSON-LD metadata
var respecConfig = {
  doJsonLd: true,
  canonicalURI: "TR",
  license: "w3c-software-doc",
};
  • Also requires canonicalURI and license to be set for the JSON-LD to be complete
  • Generated metadata includes: document title, editors, abstract, citations, publish date, copyright
  • The JSON-LD uses the TechArticle schema.org type

6.8 errata📝 Edit

Type: string Default: undefined

URL to the errata document for this specification. Shown in the document header. Typically only relevant for "REC" (Recommendation) documents.

Basic usage📝 Edit

  • Primarily used for "REC" documents that have accumulated corrections since publication
  • For active specs still being edited, corrections go into the spec itself rather than a separate errata document

6.9 group📝 Edit

Type: 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.

Basic usage📝 Edit

Example 127: Associate with a Working Group
var respecConfig = {
  group: "webapps",
};
Example 128: Multiple groups (joint deliverable)
var respecConfig = {
  group: ["webapps", "css"],
};
Example 129: Disambiguate group type
var respecConfig = {
  group: "wg/wot",  // "wg/", "cg/", "ig/", or "bg/" prefix
};

Valid specStatus values per group type📝 Edit

The group type determines which specStatus values are valid. Using the wrong combination produces an error.

Group type Examples Valid specStatus values
Working Group (wg/) "webapps", "css" "ED", "FPWD", "WD", "CR", "CRD", "PR", "REC", "NOTE", "DNOTE", …
Community Group (cg/) "wicg", "webassembly" "CG-DRAFT", "CG-FINAL"
Business Group (bg/) "BG-DRAFT", "BG-FINAL"
Interest Group (ig/) "NOTE", "DNOTE"
Example 130: Community Group document — must use CG-DRAFT not ED
var respecConfig = {
  group: "wicg",
  specStatus: "CG-DRAFT",  // NOT "ED" — that's for Working Groups
};
  • Browse available group short names at respec.org/w3c/groups/
  • The group option auto-populates patent policy, group homepage link, mailing list, and participant count
  • For closed groups not listed at respec.org/w3c/groups/, use the type/shortname form (e.g. "wg/csv") and refer to w3.org/groups/ to find the correct values
  • When a CG and WG share the same shortname, use the prefix form to disambiguate: "cg/wot" vs "wg/wot"
  • Replaces: wg, wgId, wgURI, wgPatentURI, wgPublicList — do not use those deprecated options alongside group

6.10 implementationReportURI📝 Edit

Type: string Default: undefined

URL of the implementation report showing how implementations perform against the test suite. Shown in the document header as an "Implementation report" link. Required for Candidate Recommendation ("CR") documents.

Basic usage📝 Edit

  • Required or strongly recommended for "CR" — reviewers need to see implementation status
  • Can link to a wpt.fyi results page, a GitHub page, or a custom report

6.11 latestVersion📝 Edit

Type: 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.

Basic usage📝 Edit

Example 132: Set latest version URL for a CG report
var respecConfig = {
  latestVersion: "https://wicg.github.io/my-feature/",
};
  • For standard W3C Working Group specs, you normally don't need to set this
  • Set to null to suppress the "Latest Published Version" link entirely
  • For Community Groups publishing on GitHub Pages, set this to your GitHub Pages URL

6.12 level📝 Edit

Type: number Default: undefined

Sets the "level" of a leveled specification. Appends "Level N" to the document title and adds the level number to shortName. Used by CSS Working Group and other groups that publish progressive levels of a spec.

Basic usage📝 Edit

Example 133: CSS Color Level 5
var respecConfig = {
  level: 5,
  shortName: "css-color",
  // Title becomes: "CSS Color Level 5"
  // shortName becomes: "css-color-5"
};
  • Appends "Level N" to the document title
  • Appends the level number to shortName (e.g. css-color-5)
  • Level must be a non-negative integer
  • ⚠️ Use with care — leveled specs are hard to maintain if multiple levels evolve concurrently. Only use if your working group has a clear leveling policy (like CSS WG does).

6.13 noRecTrack📝 Edit

Type: 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.

Basic usage📝 Edit

Example 134: Document not on the Recommendation track
var respecConfig = {
  specStatus: "NOTE",
  noRecTrack: true,
};
  • Use when specStatus is a Notes-track value ("DNOTE", "NOTE", "STMT") to make this explicit
  • ReSpec warns if a Rec-track specStatus is set alongside noRecTrack: true

6.14 prEnd📝 Edit

Type: string Default: undefined

The end date of the Proposed Recommendation review period, in "YYYY-MM-DD" format. Required when specStatus is "PR".

Basic usage📝 Edit

Example 135: Proposed Recommendation with review end date
var respecConfig = {
  specStatus: "PR",
  crEnd: "2025-06-01",
  prEnd: "2025-08-01",
};
  • Required for "PR" — ReSpec will warn if missing
  • "PR" also requires crEnd
  • Format must be "YYYY-MM-DD"

6.15 prevED📝 Edit

Type: string Default: undefined

URL of a previous Editor's Draft location. Used when a document has moved, been transferred between groups, or split from a larger document — situations where the version control history is no longer directly accessible.

Basic usage📝 Edit

Example 136: Spec that moved from another location
var respecConfig = {
  prevED: "https://old-location.example.org/my-spec/",
};
  • Rarely needed — most specs stay in the same repository
  • Use when a spec has genuinely moved and linking to the previous ED location helps readers find the history

6.16 previousDiffURI📝 Edit

Type: string Default: undefined

The URL to use as the "old" version when generating a diff-marked document. By default, ReSpec uses the previous published version. Override this to diff against a different version.

Basic usage📝 Edit

Example 137: Diff against an earlier version
var respecConfig = {
  previousPublishDate: "2024-01-15",
  previousMaturity: "WD",
  // Override: diff against the very first WD, not the immediately previous one
  previousDiffURI: "https://www.w3.org/TR/2021/WD-my-spec-20210301/",
};
  • Rarely needed — most specs just diff against the immediately previous version
  • Use when the default diff target isn't the version you want to compare against

6.17 previousMaturity📝 Edit

Type: 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.

Basic usage📝 Edit

Example 138: Republishing as a Working Draft
var respecConfig = {
  specStatus: "WD",
  publishDate: "2025-06-15",
  previousPublishDate: "2024-12-01",
  previousMaturity: "WD",
};
  • Always set together with previousPublishDate
  • The value must be a valid specStatus identifier (e.g. "WD", "CR", "FPWD")
  • ReSpec does not validate whether the progression makes sense — the W3C Link Checker will catch mismatches before publication
  • For "FPWD" (first publication), omit both fields

6.18 previousPublishDate📝 Edit

Type: 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").

Basic usage📝 Edit

Example 139: Republishing a Working Draft
var respecConfig = {
  specStatus: "WD",
  publishDate: "2025-06-15",
  previousPublishDate: "2024-12-01",
  previousMaturity: "WD",
};
  • Always set together with previousMaturity
  • For "FPWD" (first publication), omit both — there is no previous version
  • Format must be "YYYY-MM-DD"

6.19 prevRecShortname📝 Edit

Type: string Default: undefined

The shortName of a previous version of this document that is a W3C Recommendation. Used when publishing a new version (e.g., Level 2) of an existing Recommendation.

Basic usage📝 Edit

Example 140: Level 2 spec superseding Level 1
var respecConfig = {
  shortName: "css-grid-2",
  prevRecShortname: "css-grid-1",
};
  • Generates a "Previous Recommendation" link in the document header
  • Use when the current spec supersedes a Recommendation under a different shortName
  • Also see prevRecURI to specify the full URL instead of the shortName

6.20 prevRecURI📝 Edit

Type: string Default: auto-generated from prevRecShortname

The URL of the previous W3C Recommendation this document supersedes. Use a dated URL for stability.

Basic usage📝 Edit

Example 141: Previous Recommendation dated URL
var respecConfig = {
  prevRecURI: "https://www.w3.org/TR/2014/REC-css-color-3-20140805/",
};
  • Prefer a dated URL over the /TR/shortname/ shortcut — if the Recommendation is later rescinded, the undated link may become stale or redirect
  • If omitted but prevRecShortname is set, ReSpec auto-generates https://www.w3.org/TR/prevRecShortname/

6.21 submissionCommentNumber📝 Edit

Type: string Default: undefined

The W3C Team comment number for a Member Submission. Required when specStatus is "Member-SUBM".

Basic usage📝 Edit

Example 142: Member Submission with comment number
var respecConfig = {
  specStatus: "Member-SUBM",
  submissionCommentNumber: "03",
};
  • Generates a link to https://www.w3.org/Submission/[year]/[number]/Comment/ in the header
  • W3C staff assigns this number as part of the submission process

6.22 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.

Migration📝 Edit

Example 143: Replace wgPublicList with group
// Before:
// wgPublicList: "public-webapps",

// After:
var respecConfig = {
  group: "webapps",
};

7. Special <section> IDs

7.1 <section id="conformance">📝 Edit

A <section> with id="conformance" tells ReSpec to insert the standard RFC 2119 conformance boilerplate. Add any spec-specific conformance text after the placeholder — ReSpec will prepend the boilerplate above it.

If your spec uses RFC 2119 keywords (MUST, SHOULD, MAY, etc.), you need this section. ReSpec will warn you if RFC 2119 keywords are present but the conformance section is missing:

<div class="advisement">

Warning: Document uses RFC2119 keywords but lacks a conformance section.</div>
Hint: Please add a <section id="conformance">.
Example 144: Conformance section with custom text
<section id="conformance">
  <p>This specification defines conformance criteria that apply
  to a single product: the <em>widget</em>.</p>
</section>

Suppressing the boilerplate📝 Edit

Add class="override" to take full control and write your own conformance text without any generated boilerplate:

Example 145: Custom conformance text, no generated boilerplate
<section id="conformance" class="override">
  <h2>Conformance</h2>
  <p>This document defines requirements for implementations. An implementation
  is conformant if it satisfies all the normative requirements herein.</p>
</section>
  • Required for specifications that contain normative material (MUST, SHALL, etc.)
  • The boilerplate includes the RFC 2119 keyword definitions ("MUST", "SHOULD", "MAY", etc.)
  • Your custom text follows the boilerplate — it can include additional conformance classes, profiles, or requirements
  • If the section is empty, only the boilerplate is shown
  • class="override" skips all generated content — the section is left exactly as authored

7.2 gh-contributors📝 Edit

Automatically 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.

Example 146: Contributors section
<section>
  <h2>Contributors</h2>
  <p>We thank the following contributors:</p>
  <ul id="gh-contributors"></ul>
</section>
Example 147: Inline contributor list
<p>
  Also thanks to: <span id="gh-contributors"></span>.
</p>
  • Contributors are sorted alphabetically by GitHub username or display name
  • Requires github to be configured in respecConfig
  • Fetches contributor data from the GitHub API — contributors list may be large for active repositories

7.3 <section id="idl-index">📝 Edit

Generates a consolidated WebIDL index — all the WebIDL definitions in the spec gathered into one place, formatted as a single block.

Example 148: IDL index appendix
<section id="idl-index" class="appendix">
  <!-- All WebIDL from across the document appears here -->
</section>
Example 149: IDL index with custom heading and intro
<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>

Excluding IDL blocks📝 Edit

Add class="exclude" to any <pre class="idl"> to keep it out of the IDL index — useful for non-normative illustrative examples:

Example 150: Excluding a block from the IDL index
<pre class="idl exclude">
  // This example IDL is not normative
  interface Example {};
</pre>

IDL blocks inside non-normative sections (class="informative") are automatically excluded.

  • Collects every normative <pre class="idl"> block in the document and combines them
  • IDL blocks with class="exclude" or inside informative sections are skipped
  • If the spec has no normative WebIDL, the section shows: "This specification doesn't normatively declare any Web IDL."
  • Add custom content (heading, intro paragraph) before the IDL — ReSpec appends the IDL after it
  • Typically placed as an informative appendix

7.4 <section id="index">📝 Edit

Generates a comprehensive terms index — all terms defined in this spec and all terms referenced from other specs, in a single searchable section.

Example 151: Terms index appendix
<section id="index" class="appendix">
  <!-- ReSpec generates the index here -->
</section>
Example 152: With custom heading and intro
<section id="index" class="appendix">
  <h2>Index of All Terms</h2>
  <p>Defined terms and external references used in this specification.</p>
  <!-- Index generated after custom content -->
</section>
Example 153: Show full spec titles instead of shortnames
<section id="index" class="appendix prefer-full-spec-title">
  <!-- Shows "DOM Standard" instead of "[DOM]" -->
</section>
  • Shows both locally defined terms (<dfn>) and externally referenced terms (via xref)
  • Clicking a term in the index jumps to its definition or first use in the document
  • Adding class="prefer-full-spec-title" shows full spec titles (e.g., "DOM Standard") instead of shortnames (e.g., "[DOM]")
  • Typically placed as an informative appendix

7.5 <section id="issue-summary">📝 Edit

Generates a consolidated list of all issue boxes referenced throughout the document.

Example 154: Issue summary appendix
<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>
  • Collects all elements with class="issue" across the document
  • Each entry includes the issue number (if data-number is set), the title (if title attribute is set), and a link back to the issue in the document
  • Useful for tracking all open issues in a spec at a glance during review
  • Typically placed as an informative appendix

7.6 <section id="references">📝 Edit

Adding a <section id="references"> lets you add custom content to the references section. ReSpec appends the auto-generated normative and informative references after any custom content.

Example 155: References section with custom intro
<section id="references">
  <p>Unless otherwise specified, all references are to the
  latest published version of the respective specification.</p>
  <!-- Normative and informative references follow automatically -->
</section>
  • If you don't add <section id="references">, ReSpec still generates the references section automatically
  • Custom content is placed before the auto-generated reference lists
  • References are generated from [[CITE]] usage throughout the document plus any localBiblio entries

7.7 <section id="tof">📝 Edit

Automatically generates a Table of Figures — a list of all <figure> elements in the document, linked to each figure by its <figcaption>.

Example 156: Table of Figures section
<section id="tof">
  <!-- ReSpec generates the list of figures here -->
</section>
  • All <figure> elements with a <figcaption> are included — ReSpec auto-generates IDs from the caption text if no id is set
  • ReSpec auto-generates a "Table of Figures" heading if none is provided
  • Typically placed as an appendix: <section id="tof" class="appendix">
  • Also see the auto-numbering of figures — empty <a href="#figure-id"> links auto-fill with "Figure N"

8. Special element behaviour

8.1 Dark mode📝 Edit

ReSpec supports dark mode for W3C specs via the standard color-scheme meta tag.

Enable dark mode support📝 Edit

Example 157: Enable light/dark mode support
<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.

Manual toggle📝 Edit

The ReSpec pill includes a dark mode toggle that overrides the system preference. This toggle injects a .darkmode class on <body> via JavaScript.

Writing custom CSS for dark mode📝 Edit

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; }
  • Dark mode styles are part of the W3C TR design system — only available for W3C specs
  • The .darkmode class limitation is a known architectural issue; the CSS prefers-color-scheme media query does not respond to JS-injected class names
  • For specs with heavy custom CSS, you will need to duplicate your dark-mode rules to cover both the media query and the .darkmode class

8.2 <figure>📝 Edit

Standard HTML <figure> elements are enhanced by ReSpec with automatic numbering, self-links, and cross-reference support.

Example 158: A figure with caption
<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.

  • Figures are numbered automatically ("Figure 1", "Figure 2", …)
  • A <figcaption> is required — figures without one generate a ReSpec warning
  • Empty links to a figure's id auto-populate with "Figure N"
  • A self-link (§) is generated so readers can link directly to a specific figure
  • Generate a list of all figures with tof (Table of Figures)
  • The <figcaption> should be a proper caption describing the figure, not just a title

8.3 <h1 id="title">📝 Edit

The <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.

Example 159: Title with markup
<body>
  <h1 id="title">The <code>Widget</code> Interface</h1>
  <section id="abstract">
    <p>This spec defines the Widget interface.</p>
  </section>
</body>
  • ReSpec warns if the <title> element text and the <h1 id="title"> text content don't match — keep them in sync
  • Only one <h1 id="title"> is allowed
  • The <title> element is still required for the HTML document — the <h1> overrides the rendered title only

8.4 <pre> and <code> elements📝 Edit

ReSpec automatically syntax-highlights <pre> and <code> elements using highlight.js. Highlighting runs in a Web Worker — it doesn't block the main thread.

Basic usage📝 Edit

Example 160: Auto-detected syntax highlighting
<pre>
function fetch(url) {
  return new Promise(resolve => {
    // ... JS is auto-detected
  });
}
</pre>
Example 161: Explicitly specify the language
<pre class="css">
.widget {
  display: flex;
  color: #336;
}
</pre>

Supported languages (built-in)📝 Edit

abnf, css, html, http, javascript (js), json, xml, webidl

Disable highlighting📝 Edit

Example 162: Disable for a specific block
<pre class="nohighlight">
pseudocode or plain text here
</pre>

Load additional languages📝 Edit

Example 163: Load Solidity syntax highlighting
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],
};
  • Highlighting is done in a Web Worker and is non-blocking
  • Language is auto-detected if no class is specified
  • Use nohighlight to disable for a block
  • Use nolinks to prevent auto-linking of URLs inside code blocks (Markdown mode)

8.5 <section>📝 Edit

Standard HTML <section> elements are the building blocks of a ReSpec specification. ReSpec handles heading numbering, ToC generation, ID creation, and self-links automatically.

Example 164: A basic section
<section>
  <h2>The <code>fetch()</code> method</h2>
  <p>The <code>fetch()</code> method initiates a network request.</p>
</section>
Example 165: Nested sections
<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":

Example 166: Auto-linking to a section
<p>See <a href="#infrastructure"></a> for details.</p>
<!-- Renders as: See § 2 Infrastructure for details. -->
  • Use <h2> for all top-level sections by convention (ReSpec renumbers them correctly regardless)
  • Nesting depth can go beyond <h6> — ReSpec clamps to <h6> for deep nesting
  • Add id attributes manually for stable URLs; ReSpec generates IDs from heading text if absent
  • Special section IDs: abstract, sotd, conformance, toc — these trigger specific boilerplate
  • See appendix for lettered appendix sections
  • See informative to mark a section as non-normative

8.6 <title>📝 Edit

The <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.

Example 167: Set the specification title
<!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>
  • The <title> is the simplest and recommended way to set the spec title
  • If you need markup in the title (e.g., <code> or non-ASCII characters), use <h1 id="title"> instead
  • Keep the <title> and any <h1 id="title"> in sync — ReSpec warns if they differ

9. CSS classes

9.1 .appendix📝 Edit

Marks 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.

Example 168: Appendix section
<section class="appendix">
  <h2>Acknowledgements</h2>
  <p>The editors thank the following for their contributions…</p>
</section>
  • Being an appendix does not make a section informative — combine with class="informative" if needed
  • Every section after the first appendix becomes an appendix — put appendices at the end of the document
  • Appendix IDs and the ToC show letter labels (A, B, C…) instead of numbers

9.2 .ednote📝 Edit

Marks 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.

Example 169: Editor's note about a pending issue
<p class="ednote">
  This section needs to be revised to address the i18n WG feedback.
</p>
Example 170: Editor's note with a title
<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>
  • Editor's Notes appear with a distinctive yellow box and "Editor's Note" heading
  • The title attribute adds text to the heading: "Editor's Note: [title]". It is interpreted as HTML.
  • Unlike note, editor's notes signal work-in-progress and are not intended for the published spec
  • Use issue for tracked GitHub issues; use .ednote for free-form editorial comments

9.3 .example📝 Edit

Marks a <pre>, <aside>, or other element as a numbered example. Adds an "Example N" heading with an optional title.

Example 171: Code example
<pre class="example">
  const result = navigator.credentials.get({ password: true });
</pre>
Example 172: Example with a title
<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>
Example 173: Counter-example (illegal usage)
<pre class="illegal-example">
  document.write("&lt;!-- don't do this -->");
</pre>
  • Examples are numbered automatically ("Example 1", "Example 2", …)
  • A self-link (§) is generated so readers can link directly to a specific example
  • The title attribute is interpreted as HTML — see title attributes
  • Use class="illegal-example" to mark a counter-example (renders with a different style)
  • <aside class="example"> can contain nested <pre> elements with mixed prose and code

9.4 .exclude📝 Edit

Opts an element out of specific ReSpec processing.

Example 174: Exclude from abbreviation expansion
<p>
  <abbr class="exclude" title="Application Programming Interface">API</abbr>
  is not automatically expanded here.
</p>
Example 175: Exclude WebIDL block from the IDL index
<aside class="example" title="Hypothetical API">
  <pre class="idl exclude">
  interface Example {
    undefined hypotheticalMethod();
  };
  </pre>
</aside>

Supported elements📝 Edit

Element Effect of .exclude
<abbr class="exclude"> Prevents the abbreviation from being automatically expanded
<pre class="idl exclude"> Excludes this WebIDL block from the idl-index
  • Use on IDL blocks that are illustrative examples, not normative definitions that should appear in the IDL index
  • The .exclude class does not prevent the element from being rendered — it only opts out of specific ReSpec transformations

9.5 data-export / .export📝 Edit

Applies 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.

Example 176: Export a concept definition
<p>The <dfn data-export>fetch</dfn> algorithm takes a request and returns a response.</p>

The class="export" form also works:

Example 177: Export using class syntax
<dfn class="export">request</dfn>

Prevent export📝 Edit

Example 178: Explicitly prevent export
<dfn data-noexport>internal algorithm</dfn>
  • Exported terms are indexed by Webref and become available in the xref database within ~6 hours of publication
  • Your spec must be listed in browser-specs to be indexed
  • Only export terms that other specifications actually need — internal helper concepts should not be exported
  • WebIDL interfaces, attributes, methods, etc. are automatically exported — you don't need data-export for IDL
  • Use data-noexport to explicitly prevent a definition from being exported (e.g. if it would shadow a same-named definition from another spec)
  • ⚠️ Do not place exported <dfn> elements in <section id="abstract"> or other unnumbered sections (SotD, introductory sections). Doing so causes a crash in the terms index (bug #5133). Define terms in a numbered section such as a "Terminology" or "Definitions" section instead.

9.6 .informative📝 Edit

Marks a section as non-normative. ReSpec automatically prepends the standard "This section is non-normative." paragraph.

Example 179: Informative section
<section class="informative">
  <h2>Background and Motivation</h2>
  <p>This section explains the history behind this feature…</p>
</section>
  • Use for introductions, use cases, examples, and explanatory material that readers are not required to implement
  • The "This section is non-normative." prefix is added automatically — don't add it manually
  • Combine with class="appendix" for informative appendices: class="appendix informative"
  • Note that ednote sections are also non-normative and are typically stripped before publication

9.7 .issue📝 Edit

Marks content as an open issue box. When used with github, can automatically embed a GitHub issue by number.

Example 180: Inline issue note
<div class="issue">
  <p>We need to decide whether this should be synchronous.</p>
</div>
Example 181: Embed a GitHub issue by number
<div class="issue" data-number="363"></div>
Example 182: Issue with a title
<p class="issue" title="Needs resolution">
  Should this be normative?
</p>
Example 183: Feature at Risk (W3C Rec-track docs)
<div class="issue atrisk" data-number="42">
  <p>This feature may be removed before publication.</p>
</div>

Feature at Risk📝 Edit

Adding class="atrisk" alongside class="issue" renders the heading as "(Feature at Risk) Issue N" — the W3C Process convention for marking features under review during CR.

When atRiskBase is configured, data-number links to that tracker instead of issueBase:

Example 184: atRiskBase config
var respecConfig = {
  issueBase: "https://github.com/example/repo/issues/",
  atRiskBase: "https://github.com/example/repo/issues/",
};
  • When data-number is set and github is configured, ReSpec downloads the issue content from GitHub and embeds it
  • GitHub issues with state: "CLOSED" render with a closed CSS class
  • The title attribute is interpreted as HTML — see title attributes
  • Works inline: <span class="issue">…</span> renders as a compact inline issue marker
  • Use issue-summary to generate a collected list of all issues in the document
  • Issues are numbered automatically (e.g. "Issue 1", "Issue 2")

9.8 lint-ignore📝 Edit

The lint-ignore class suppresses specific linting warnings on individual elements without disabling the entire rule globally.

Suppress unused definition warning📝 Edit

When no-unused-dfns is enabled, suppress for one definition:

Example 185: Suppress unused-dfn warning
<dfn class="lint-ignore">internal helper concept</dfn>

Suppress informative-dfn warning📝 Edit

When informative-dfn is enabled, suppress for one link:

  • lint-ignore is element-level — it only suppresses the warning on that specific element, not all occurrences
  • Use sparingly — it's better to fix the underlying issue than to suppress it
  • Compare with data-lint-ignore="rule-name" (attribute form) for suppressing specific rules on tables and other elements

9.10 .nohighlight📝 Edit

Disables syntax highlighting for a specific <pre> code block. By default, ReSpec syntax-highlights all <pre> elements.

Example 188: Code block without syntax highlighting
<pre class="nohighlight">
This is plain text or pseudocode.
It will not be syntax-highlighted.
</pre>
  • Without .nohighlight, ReSpec uses highlight.js to auto-detect and highlight the language
  • Use .nohighlight for pseudocode, ABNF grammars, or other content where syntax highlighting would be distracting
  • To specify a language explicitly instead: <pre class="js"> for JavaScript, <pre class="css"> for CSS, etc.

9.12 .note📝 Edit

Marks content as a note. Generates a labelled "Note" box with the content.

Example 190: Block note with a title
<div class="note">
  <p>Authors must not rely on the computed value being identical
  across different implementations.</p>
</div>
Example 191: Note with a custom title
<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>

Variants📝 Edit

Class Renders as
.note Note box
.note with title attribute "Note: [title]" header
.warning Warning box (see .warning)
  • Works on block elements: <div>, <p>, <aside>, <section>
  • Also works inline: <span class="note">…</span> renders as a compact inline note
  • The title attribute is interpreted as HTML — see title attributes
  • Numbered notes get a counter in the heading (e.g. "Note 1")
  • For editor-facing notes not meant for the published spec, use ednote instead

9.13 .notoc📝 Edit

Excludes a section from the Table of Contents.

Example 192: Section excluded from ToC
<section class="notoc" id="acknowledgements">
  <h2>Acknowledgements</h2>
  <p>The editors thank...</p>
</section>
  • Only affects the immediate section — child sections are also excluded
  • data-max-toc="0" has the same effect as class="notoc" but can be applied from data-include context
  • To suppress the entire ToC, use noTOC config option

9.14 .numbered (tables)📝 Edit

Adding class="numbered" to a <table> enables automatic numbering, caption linking, and inclusion in a Table of Tables.

Example 193: A numbered table
<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>

Generate a List of Tables📝 Edit

Example 194: List of Tables section
<section id="list-of-tables">
  <!-- All numbered tables are listed here automatically -->
</section>
  • A <caption> is required — the no-captionless-tables linting rule enforces this
  • <caption> must be the first child of <table>
  • Empty links to a numbered table's id auto-fill with "Table N" text
  • Tables without class="numbered" are not auto-numbered or included in the List of Tables

9.15 .override📝 Edit

⚠️ Last resort only. Adding class="override" to a section that ReSpec would normally auto-generate replaces the generated content entirely with your custom content.

Example 195: Override the Status of This Document section
<section id="sotd" class="override">
  <h2>Status of This Document</h2>
  <p>This document is an experimental draft for discussion only.</p>
</section>

Sections that can be overridden📝 Edit

  • <section id="sotd"> — Status of This Document
  • <section id="conformance"> — Conformance
  • Only use when ReSpec's generated boilerplate is genuinely inappropriate for your document
  • Overriding sotd bypasses the standard W3C status boilerplate — you are responsible for all required W3C publication text
  • Most cases where you want to customize SotD can be handled by adding content to the section without the .override class — ReSpec will prepend the boilerplate and keep your content

9.16 .permission / data-dfn-type="permission"📝 Edit

Marks a <dfn> as defining a browser permission string, as used in the Permissions API. The permission name should be a quoted string.

Example 196: Define a browser permission
<p>
  The Geolocation API is identified by the powerful feature name
  <dfn class="permission">"geolocation"</dfn>.
</p>

Or equivalently:

Example 197: Define a permission using data-dfn-type
<dfn data-dfn-type="permission">"geolocation"</dfn>
  • Permission names are quoted strings per the Permissions API spec (e.g., "geolocation", "camera")
  • Using class="permission" is equivalent to data-dfn-type="permission"
  • Permission definitions are exported and linkable via xref

9.17 .practice / .practicedesc / .practicelab📝 Edit

A set of CSS classes for marking up best practices in a specification. Generates a numbered best practice box with a label and description.

Example 198: Best practice box
<div class="practice">
  <p class="practicedesc">
    <span class="practicelab">Use semantic HTML</span>
    Use the most semantically appropriate HTML element for each piece of content.
    Do not use `<div>` where a `<section>`, `<article>`, or `<nav>` would be more appropriate.
  </p>
</div>

Classes📝 Edit

Class Applied to Purpose
.practice <div> Container for the best practice
.practicedesc <p> The description text
.practicelab <span> inside .practicedesc The label/name of the practice
  • Best practices are automatically numbered
  • Less commonly used than note or example — mainly used by older W3C specs that use this pattern

9.18 practicedesc📝 Edit

A 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>

9.19 practicelab📝 Edit

A <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>

9.20 .remove📝 Edit

Marks an element to be removed from the document during processing. This is how the ReSpec <script> elements and config blocks are handled — they are stripped after processing completes.

Example 199: Remove helper content after processing
<div class="remove">
  <p>This content is for authoring convenience only and won't appear in the output.</p>
</div>
Example 200: ReSpec itself uses this on script elements
<script src="respec-w3c.js" class="remove" async></script>
<script class="remove">
  var respecConfig = { ... };
</script>
  • The .remove class strips the element entirely from both the live preview and the saved HTML export
  • For content that should only be stripped from the saved/exported HTML (but remain visible during live authoring), use .removeOnSave instead
  • All <script class="remove"> elements in a ReSpec document use this pattern

9.21 .removeOnSave📝 Edit

Marks 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.

Example 201: Content removed at export time
<div class="removeOnSave">
  <p class="ednote">Remember to update the SotD before publication.</p>
</div>
Example 202: Inline element removed at export
<p>
  See <a href="https://respec.org/xref" class="removeOnSave">(xref search)</a>
  for resolving ambiguous terms.
</p>
  • The ReSpec pill itself uses removeOnSave — it disappears from saved HTML
  • The caniuse and mdn widgets also use removeOnSave by default (configurable via removeOnSave option)
  • Content with class="removeOnSave" is fully removed — not just hidden — in the exported HTML

9.22 W3C Specific

9.22.1 <section id="sotd" class="updateable-rec">📝 Edit

Marks a Proposed Recommendation as intending to allow new features once it becomes a W3C Recommendation. ReSpec adds the required boilerplate text automatically.

Example 203: Mark spec as allowing future additions
<section id="sotd" class="updateable-rec">
  <p>This specification may be amended by adding new features
  in future levels.</p>
</section>
  • Only relevant for "PR" (Proposed Recommendation) documents heading toward "REC"
  • Enables the W3C Process 2020 mechanism for publishing updated Recommendations
  • ReSpec validates consistency between specStatus and this class

10. HTML Attributes

10.1 data-abbr📝 Edit

Applies 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.

Example 204: Auto-generate abbreviation
<dfn data-abbr>user agent</dfn>
<!-- Renders as: user agent (UA) -->
Example 205: Explicit abbreviation
<dfn data-abbr="PoS">point of sale</dfn>
<!-- Renders as: point of sale (PoS) -->
  • With no value (or empty string), ReSpec generates the abbreviation from the capitalized initial letters of the term: "user agent" → "UA"
  • With an explicit value, that value is used as-is
  • The <abbr> element added uses the full term as its title attribute, enabling screen reader and hover tooltip support
  • The abbreviation is automatically added as an alias (data-lt) on the <dfn>, so [=UA=] will link to the definition of "user agent" without needing a separate alias declaration

10.2 data-cite📝 Edit

Applies to: <a>, <dfn>

Manually links an element to a specific term, section, or spec. Use this when xref automatic linking doesn't work, or when you need a precise anchor.

When to use data-cite📝 Edit

Situation Use
Term is in the xref database [=term=] shorthand (preferred)
Term is not exported by the defining spec data-cite="SPEC#anchor"
Linking to a section heading (not a term) data-cite="SPEC#section-id"
Linking to the spec itself (bibliography) data-cite="SPEC"
Documenting a term defined elsewhere (re-exporting) <dfn data-cite="SPEC#dfn-id">

Syntax📝 Edit

data-cite="[!]SPEC-ID[/path-to-doc][#fragment]"
  • ! — normative citation (omit for informative)
  • SPEC-ID — shortname from SpecRef
  • /path-to-doc — sub-path for multi-page specs
  • #fragment — anchor ID in the target document
Example 207: Normative citation
<a data-cite="!FETCH#concept-request">request</a>
Example 208: Re-export a term from another spec
<p>The <dfn data-export data-cite="DOM#concept-event">event</dfn> is...</p>
Example 210: Cite a spec with no specific anchor (adds to bibliography)
<p>This is defined in [[FETCH]] — see <a data-cite="FETCH">the Fetch Standard</a>.</p>
Example 211: Multi-page spec with explicit path
<a data-cite="HTML/webappapis.html#event-loop">event loop</a>

<dfn data-cite> — re-exporting terms📝 Edit

When your spec needs to use and expose a term defined elsewhere, mark a local <dfn> with data-cite pointing to the canonical definition. This tells ReSpec where the term lives without defining it locally, and makes it linkable within your spec:

Example 212: Making an external term locally linkable
<!-- This lets other parts of your spec use [=request=] to link here -->
<p>A <dfn data-cite="FETCH#concept-request" data-export>request</dfn> is...</p>
  • Browse spec shortnames and anchor IDs at respec.org/xref
  • Always prefer [=term=] when the term is in the xref database — data-cite is for exceptions
  • When using data-cite="SPEC" without a fragment, the spec is added to the bibliography automatically

10.3 data-dfn-for📝 Edit

Applies 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.

Example 213: Define members of an interface
<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&lt;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>
Example 214: Disambiguate same-named definitions
<dfn data-dfn-for="Request">method</dfn>
<dfn data-dfn-for="Response">type</dfn>
  • Set data-dfn-for on a <section> to apply the context to all <dfn> elements within that section (avoids repeating it on every dfn)
  • Use data-link-for to set the default context for links within a section
  • Required when two different interfaces have members with the same name — disambiguates which one you're defining
  • WebIDL members inside <pre class="idl"> automatically get data-dfn-for set from their parent interface; you only need this for the prose dfns

10.4 data-dfn-type📝 Edit

Applies 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.

Example 215: Explicit type for an abstract operation
<p>To <dfn data-dfn-type="abstract-op">process a widget</dfn>, run these steps:</p>
Example 216: HTTP header definition
<p>The <dfn data-dfn-type="http-header">Widget-Policy</dfn> response header...</p>

Valid values for manual use📝 Edit

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)

IDL types (set automatically)📝 Edit

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

  • The [= term =] shorthand links to dfn or abstract-op type definitions
  • The {{ term }} shorthand links to IDL type definitions
  • When data-dfn-for is set, type defaults to IDL unless explicitly overridden
  • If unsure, omit data-dfn-type and let ReSpec infer it

10.5 data-format📝 Edit

Applies 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.

Example 217: Markdown section in an HTML document
<section data-format="markdown">

## Introduction

This is **Markdown** content inside an HTML document.

- List item one
- List item two

</section>
  • Only supports "markdown" as a value
  • The content is processed as GitHub Flavored Markdown — headings create nested <section> elements automatically
  • For including external Markdown files, combine with data-include and data-include-format="markdown"
  • See the Markdown guide for detailed usage

10.6 data-include📝 Edit

Applies 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).

Example 218: Include an HTML file
<section data-include="sections/introduction.html"></section>
Example 219: Include a Markdown file
<section data-include="sections/api.md"
         data-include-format="markdown"></section>
Example 220: Replace the element entirely
<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
  • Paths are relative to the including document
  • Includes are recursive up to a maximum depth of 3
  • Included content is processed by ReSpec just as if it were in the original document (WebIDL, definitions, links, etc. all work)
  • Must be served over HTTP/HTTPS — does not work with file:/// URLs. Use a local server during development.
  • Circular includes are not detected — avoid include loops

10.7 data-include-format📝 Edit

Applies to: elements with data-include

Specifies the format of the included content.

Example 221: Include plain text
<section data-include="changelog.txt"
         data-include-format="text"></section>
Example 222: Include Markdown
<section data-include="intro.md"
         data-include-format="markdown"></section>

Values📝 Edit

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 interpretation

10.8 data-include-replace📝 Edit

Applies to: elements with data-include

When present, the including element is replaced by the included content rather than having the content inserted inside it.

Example 223: Replace element with included content
<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>

Compared to default behavior📝 Edit

Example 224: Default: content inserted inside element
<section data-include="content.html">
  <!-- content.html's markup is placed here, inside the <section> -->
</section>
Example 225: With replace: element is substituted
<section data-include="full-section.html"
         data-include-replace="true">
  <!-- The <section> element itself is replaced by full-section.html's content -->
</section>
  • Use when the included file provides its own wrapper element (e.g., the file is a full <section>)
  • Without data-include-replace, you'd end up with nested <section> elements
  • Any value for the attribute triggers replacement ("true", "1", or just the presence of the attribute)

10.11 data-local-lt📝 Edit

Applies 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.

Example 228: Local aliases that aren't exported
<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 -->
  • Separate multiple local alternatives with |
  • In contrast, data-lt alternatives are exported (the first data-lt value becomes the canonical xref export name)
  • Use data-local-lt for verb forms, gerunds, and other grammatical variants that shouldn't clutter the global xref namespace

10.12 data-lt📝 Edit

Applies to: <dfn>, <a>

Defines alternative linking terms for a definition (or an alternative text for a link). Multiple alternatives are separated by |.

Example 229: Definition with alternative terms
<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=]
  • Alternatives are matched case-insensitively
  • The first alternative in data-lt becomes the canonical export name for cross-spec linking
  • For pluralization, see pluralize and data-lt-no-plural
  • data-lt replaces the element's text content as the term; data-local-lt adds alternatives only visible within this document
  • See also: data-local-lt for document-local alternatives

10.13 data-lt-no-plural📝 Edit

Applies to: <dfn>

Disables automatic pluralization for a specific definition when pluralize is enabled globally.

Example 232: Prevent wrong plural for an acronym
<dfn data-lt-no-plural>API</dfn>
<!-- Without this, 'APIs' would auto-link even if that seems wrong -->
  • Use for acronyms, brand names, and terms where auto-pluralization would produce incorrect or awkward forms
  • Has no effect if pluralize is disabled
  • Can be combined with data-lt to define explicit alternative forms while still preventing auto-pluralization of the base term

10.14 data-lt-noDefault📝 Edit

Applies 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.

Example 233: Disambiguate two definitions with the same name
<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 -->
  • Without data-lt-noDefault, having two <dfn> elements with the same text content would cause a disambiguation error
  • data-lt-noDefault lets you give a definition a unique programmatic name (via data-lt) while the display text can still match another definition

10.15 data-max-toc📝 Edit

Applies 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.

Example 234: Limit ToC depth within a section
<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>
Example 235: Exclude section from ToC entirely
<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 ToC
  • Depth is counted from the section itself (not the document root)
  • See maxTocLevel for a document-wide depth limit

10.16 data-number📝 Edit

Applies 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.

Example 236: Inline issue linked to GitHub
<p class="issue" data-number="42">
  <!-- ReSpec fetches and displays the content of issue #42 -->
</p>
  • When data-number is set, ReSpec fetches the issue content from GitHub and embeds it automatically
  • The element can be left empty — GitHub content is inserted by ReSpec
  • Without data-number, you can still use class="issue" for inline editorial notes without a GitHub link
  • See issue for full documentation of issue boxes

10.17 data-oninclude📝 Edit

Applies 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.

Example 237: Transform included content
<script>
  function addTimestamp(utils, content, url) {
    return content + `\n<!-- Included from ${url} -->`;
  }
</script>

<section data-include="section.html"
         data-oninclude="addTimestamp">
</section>

Function signature📝 Edit

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.

  • Functions are called in order, left to right — each receives the output of the previous
  • Functions must be globally accessible (defined in a <script class="remove"> block)
  • Runs on the raw string before HTML/Markdown parsing — useful for preprocessing

10.18 data-sort📝 Edit

Applies 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.

Example 238: Sort a list ascending (A to Z)
<ul data-sort>
  <li>Banana</li>
  <li>Apple</li>
  <li>Cherry</li>
</ul>
Example 239: Sort a definition list descending (Z to A)
<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>

Values📝 Edit

Value Sorts
"ascending" A → Z (default when attribute has no value)
"descending" Z → A
  • Sorting is shallow — only the top-level items are sorted; nested lists are untouched
  • For <dl>, the <dt> is used as the sort key; associated <dd> elements move with their <dt>
  • Sorting is locale-aware (uses JavaScript's Intl.Collator)

10.19 data-tests📝 Edit

Applies 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.

  • Value is a comma-separated list of test file paths, relative to testSuiteURI
  • testSuiteURI must be set in respecConfig — ReSpec will warn if it's missing
  • Enable the wpt-tests-exist linting rule to verify all referenced tests actually exist in WPT
  • Works best on <p> and <li> elements containing normative assertions

10.20 data-type📝 Edit

Applies to: <var>

Declares the type of a variable in an algorithm. Used with the highlightVars feature to associate a type annotation with a variable.

Example 241: Variable with explicit type
<p>Let <var data-type="Request">request</var> be a new request.</p>

The |variable:Type| shorthand is equivalent:

Example 242: Shorthand syntax
<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
  • Types are not validated against WebIDL — they are informational annotations for readers
  • See the Shorthands Guide for the full |variable:Type| syntax

10.21 dir📝 Edit

Type: string Default: "ltr"

Sets the text directionality of the document. Corresponds to the dir attribute on the <html> element.

Basic usage📝 Edit

Example 243: Right-to-left document
<html lang="ar" dir="rtl">
  • Set directly on the <html> element, not in respecConfig
  • Always pair with the correct lang attribute
  • Values: "ltr" (left-to-right), "rtl" (right-to-left), "auto"

10.22 lang📝 Edit

Type: string Default: "en"

Sets the language of the document. Corresponds to the lang attribute on the <html> element.

Basic usage📝 Edit

Example 244: French-language document
<html lang="fr">
  • Set directly on the <html> element, not in respecConfig
  • Use BCP 47 language tags (e.g. "en", "fr", "zh-Hans", "ar")
  • Some ReSpec-generated strings are localized for supported languages (see i18n support)
  • Always pair with the correct dir attribute for RTL languages

11. Custom Elements

11.1 <rs-changelog>📝 Edit

A 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.

Example 245: Changes since a tag
<p>Changes since the CR snapshot:</p>
<rs-changelog from="CR"></rs-changelog>
Example 246: Changes between two points
<rs-changelog from="v1.0" to="v2.0"></rs-changelog>
Example 247: Monorepo — filter to a specific path
<rs-changelog from="CR" path="payment-request/index.html"></rs-changelog>
Example 248: Filter commits with a function
<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>

Attributes📝 Edit

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

Filter function📝 Edit

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.

12. Special properties

12.1 document.respec📝 Edit

ReSpec adds a respec object to document when it loads. Use it to wait for processing to complete, inspect errors and warnings, or export the processed HTML.

document.respec.ready📝 Edit

A Promise that resolves when ReSpec finishes all processing (including postProcess functions).

Example 249: Wait for ReSpec to finish
<script>
  document.addEventListener("DOMContentLoaded", async () => {
    await document.respec.ready;
    console.log("Errors:", document.respec.errors);
    console.log("Warnings:", document.respec.warnings);
  });
</script>

document.respec.errors📝 Edit

An array of errors found during processing.

document.respec.warnings📝 Edit

An array of warnings found during processing.

Each item in errors and warnings has:

Property Type Description
message string The error/warning message text
plugin string Name of the ReSpec plugin that generated it (e.g. "core/xref")
hint string Optional suggestion for how to fix it
title string Short form of the message (used as element tooltip)
elements HTMLElement[] The offending elements in the document, if applicable
details string Additional context or explanation
cause object The underlying error that caused this one, if any

document.respec.version📝 Edit

The current ReSpec version string (semver, e.g. "35.8.0").

document.respec.toHTML()📝 Edit

Returns a Promise that resolves with the fully-processed document markup as a string — the same output as "Save as HTML".

Example 250: Export processed HTML programmatically
<script>
  document.addEventListener("DOMContentLoaded", async () => {
    await document.respec.ready;
    const html = await document.respec.toHTML();
    // Send to a server, save to disk, etc.
    await fetch("/save", { method: "POST", body: html });
  });
</script>
  • Always await document.respec.ready before reading errors/warnings — the arrays are populated incrementally during processing
  • The deprecated document.respecIsReady was a bare Promise on document; the modern form is document.respec.ready

13. Deprecated Options

13.1 addPatentNote📝 Edit

⚠️ Deprecated and removed. This option is no longer supported.

If you need patent-related notes, write them directly into the <section id="sotd"> (Status of This Document) section.

13.2 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.

13.3 tocIntroductory📝 Edit

⚠️ Deprecated and removed. Use the .notoc CSS class instead, or data-max-toc on individual sections.

Previously caused introductory sections (Abstract, SotD, etc.) to appear in the Table of Contents.

13.4 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.

Migration📝 Edit

Example 251: Old approach (deprecated)
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",
};
Example 252: New approach
var respecConfig = {
  group: "payments",
};

See group for the full list of available group short names.

13.5 wgId📝 Edit

⚠️ Deprecated. Use group instead.

Previously used to specify the numeric W3C Working Group identifier. The group option replaces this automatically.

Migration📝 Edit

Example 253: Replace wgId with group
// Before:
// wgId: 107714,

// After:
var respecConfig = {
  group: "webapps", // short name — see respec.org/w3c/groups/
};

13.6 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.

Migration📝 Edit

Example 254: Replace wgPatentURI with group
// Before (error-prone):
// wgPatentURI: "https://www.w3.org/2004/01/pp-impl/83482/status",

// After (auto-configured correctly):
var respecConfig = {
  group: "webapps",
};

13.7 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.

Migration📝 Edit

Example 255: Replace wgURI with group
// Before:
// wgURI: "https://www.w3.org/groups/wg/webapps/",

// After:
var respecConfig = {
  group: "webapps",
};

A. ReSpec Ecosystem📝 Edit

B. Person objects📝 Edit

A person object is used by editors, authors, and formerEditors. Only name is required.

Full example📝 Edit

Example 256: Person object with all fields
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",
        }
      ],
    },
  ],
};

Fields📝 Edit

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📝 Edit

Each 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

C. Common Errors📝 Edit

This page lists some common ReSpec errors and their mitigation.

Couldn't match TERM to anything in the document or in any other document cited in this specification📝 Edit

Screenshot of a ReSpec definition linking error

To fix this issue, follow these steps:

Is the term defined in some other document/specification?

  1. Search for the term using XRef Search UI. If the term is found:
    1. If the error message above does not contain the specification where term is defined, add the specification shortname to xref's specs.
    2. Otherwise, the error is due to an invalid for-context (i.e., term is defined in-context of some other term) or type-context (like referencing an exception using syntax meant for referencing concepts). Copy-paste the "How to Cite" of the relevant match from XRef Search UI.
  2. If the term is not found:
    1. Try searching for similar terms. The term might not be defined exactly. Use the shorthands syntax to alias the term in prose if needed.
    2. Check if the term is exported from the other spec, i.e., the <dfn> should have a "export" css class.
      1. If the term is not exported, ask the specification editors to export it. Feel free to ping ReSpec maintainers if you need help.
      2. If the term is exported but not found through XRef Search UI, then the specification might not be in our database. Please file an issue at ReSpec repository or contact ReSpec maintainers by other means.
        1. Note: Terms from ECMA/IETF specifications are not presently available in the terms database. Use the data-cite attribute to reference those terms.

Is the term defined in same document?

  1. If it's a WebIDL term:
    1. Remember that WebIDL terms are case-sensitive.
    2. Use the WebIDL linking syntax.
    3. Provide proper for-context using either WebIDL linking syntax or data-link-for.
  2. If it's not a WebIDL term (i.e., it's a "concept"):
    1. Use the Concepts linking syntax
    2. Provide proper for-context using either Concepts linking syntax or data-link-for.

D. Developers Guide

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

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.

D.1 ReSpec's architecture

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:

  1. Load the profile + all the plugins (but don't "run" them yet!).
  2. Wait for the document's "DOMContentLoaded" event to fire.
  3. Once DOM is ready, run each plugin in order, waiting for each plugin to finish.

D.2 Core Base runner (core/base-runner.js)

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.

D.3 Plugins

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):

Warning users of errors

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!

D.4 pnpm start

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.

D.5 Built-in HTTP server

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.

Testing

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".

Interactive mode

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.

Testing without opening browser window

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.

Custom profiles

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:

  1. Make a copy of "profiles/w3c.js", but rename it "YOUR-PROFILE-NAME.js".
  2. Open "YOUR-PROFILE-NAME.js", and remove, add, etc. any plugins you want.
  3. run: 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.

Working with your new profile

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.

Testing your 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.

E. Editing this document

This document is generated directly from the content of the ReSpec project wiki on GitHub. Thus, it can be edited in two ways:

  1. The src.html for this document provides the structure. The src.html is available in the respec-web-services repository.
  2. The ReSpec project wiki. In addition, hovering over a section heading provides a link to directly edit the relevant page in the wiki.

G. References

G.1 Normative references

[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174