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 a HTML document that brings in the ReSpec script, defines a few configuration variables, and follows a few conventions. A very small example document would be:

Example 1: A basic ReSpec document.
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Replace me with a real title</title>
    <script
      src="https://www.w3.org/Tools/respec/respec-w3c"
      class="remove"
      defer
    ></script>
    <script class="remove">
      // All config options at https://respec.org/docs/
      var respecConfig = {
        specStatus: "ED",
        editors: [{ name: "Your Name", url: "https://your-site.com" }],
        github: "some-org/mySpec",
        shortName: "dahut",
        xref: "web-platform",
        group: "my-working-group",
      };
    </script>
  </head>
  <body>
    <section id="abstract">
      <p>This is required.</p>
    </section>
    <section id="sotd">
      <p>This is required.</p>
    </section>
    <section class="informative">
      <h2>Introduction</h2>
      <p>Some informative introductory text.</p>
      <aside class="note" title="A useful note">
        <p>I'm a note!</p>
      </aside>
    </section>
    <section>
      <h2>A section</h2>
      <aside class="example">
        <p>This is an example.</p>
        <pre class="js">
        // Automatic syntax highlighting
        function someJavaScript(){}
        </pre>
      </aside>
      <section>
        <h3>I'm a sub-section</h3>
        <p class="issue" data-number="121">
          <!-- Issue can automatically be populated from GitHub -->
        </p>
      </section>
    </section>
    <section data-dfn-for="Foo">
      <h2>Start your spec!</h2>
      <pre class="idl">
        [Exposed=Window]
        interface Foo {
        attribute DOMString bar;
        undefined doTheFoo();
        };
      </pre>
      <p>The <dfn>Foo</dfn> interface represents a {{Foo}}.</p>
      <p>
        The <dfn>doTheFoo()</dfn> method does the foo. Call it by running
        {{Foo/doTheFoo()}}.
      </p>
      <ol class="algorithm">
        <li>A |variable:DOMString| can be declared like this.</li>
      </ol>
    </section>
    <section id="conformance">
      <p>
        This is required for specifications that contain normative material.
      </p>
    </section>
  </body>
</html>

1.1 Including ReSpec in HTML documents📝 Edit

The following code is used to include a ReSpec document, usually in the <head>:

Example 2: Including ReSpec into a HTML document.
  <script src="https://www.w3.org/Tools/respec/respec-w3c" class="remove" defer>
  </script>
  <script class="remove">
   var respecConfig = {
     // configuration options
   }
  </script>

ReSpec is regularly updated and this will allow you to automatically benefit from bug and security fixes and enhancements.

1.2 Configuring ReSpec📝 Edit

ReSpec is configured using a JSON-like object, which is assigned to a respecConfig JavaScript variable:

Example 3: The respecConfig global configuration object.
  <script class="remove">
   var respecConfig = {
     // configuration options
   }
  </script>

All the configurations options are listed in this document.

1.3 Structure📝 Edit

ReSpec documents are just HTML document and rely on HTML structural elements, in particular <section>, <aside>, <h2>-<h6>, <dl>, <ol> etc. In this section, we discuss how to specify various aspects of a typical document.

1.3.1 Title📝 Edit

The <title> of the document is reused as the title of the specification in the resulting document's h1. That way, they are always in sync and you need not worry about specifying it twice.

Example 4: Setting a title
<title>The Best Specification</title>

If you need to add additional markup to your title, you can still use a <h1> with id="title".

Example 5: Specification title with custom markup.
<h1 id="title">The <code>Foo</code> API</h1>

1.3.2 Subtitle📝 Edit

As with the title, you can also specify a subtitle as:

Example 6: Specification subtitle with custom markup.
<h1 id="title">The <code>Foo</code> API</h1>
<h2 id="subtitle">Subtitle here</h2>

Which is rendered as:

Screenshot of subtitle

You can also specify a subtitle configuration option in the ReSpec config, but using the markup above is preferred.

1.3.3 Editors & Authors📝 Edit

Every specification will likely have editors (at least one) and/or authors. It is left to users or standards organizations to differentiate between editors and authors (e.g., from W3C, what does an editor do?).

See the Person objects for the full list of properties you can assign.

Example 7: Specifying editors and authors.
var respecConfig = {
  // ...
  editors: [
    {
      name: "Robin Berjon",
      url: "https://berjon.com/",
      company: "W3C",
      companyURL: "https://w3c.org/",
      mailto: "[email protected]",
      note: "A Really Cool Frood",
    },
    {
      name: "Billie Berthezène-Berjon",
      company: "Catwoman",
    },
  ],
  authors: [
    {
      name: "Ada Lovelace",
      url: "https://findingada.com/",
      company: "Aristocracy",
      retiredDate: "1852-11-27",
    },
  ],
  // ...
};

Is rendered as:

Screenshot of Editors and Authors

1.3.4 Sections📝 Edit

ReSpec-based specifications require you to wrap your content in <section> elements. We provide specific information and examples on how to use <section> elements.

Sections, subsections, appendices, and whatever other structural items are marked up in ReSpec using <section> elements.

Example 8: Sections and sub-sections.
<section>
  <h2>A section</h2>
  <p>Some text.</p>
  <section class="informative">
    <h3>I'm a sub-section</h3>
    <p>Sub-section text.</p>
  </section>
</section>

Which is rendered as:

Screenshot of a  section and a sub-section=

As shown, sections are automatically numbered and uniquely id's for you. Use <section id="my-id"> specify your own id.

ReSpec sections understand some specific CSS classes: introductory, informative, and appendix.

Note

Note: You can use the special syntax [[[#some-id]]] to link to a section.

1.3.5 Table of Contents📝 Edit

In W3C specs, a table of contents (ToC) is generated automatically and placed after the "Status of This Document".

See also the maxTocLevel option to limit how deep the ToC is.

Set the configuration option noTOC to true to remove the table of content.

1.3.6 Figures & table of figure📝 Edit

To include a figure, use the <figure> and <figcaption> elements. They automatically get an id and figure number.

Example 9: Figure and list of figures.
<figure id="figure">
  <img src="figure.svg" alt="W3C Logo" />
  <figcaption>The W3C logo</figcaption>
</figure>

Which renders as:

Screenshot of a figure and figure caption

Automatic linking to figures works just as it does for sections, with [[[#some-figure]]].

To add a "List of Figures", include <section id="tof"> anywhere in the document. ReSpec will do its best to guess if it should be an appendix, introductory, or just a regular section.

Example 10: Generating a list of figures
<section id="tof" class="appendix"></section>

Renders as:

Screenshot showing a list of figures

1.3.7 Examples📝 Edit

Any <pre class="example"> or <aside class="example"> gets the additional example header and style. Content inside <pre>/<code> elements is syntax highlighted. You can specify the language in the class attribute, for example <pre class="js">.

Example 11: Creating an example
<aside class="example" title="How to use it">
  <p>
    This is how to use it.
  <p>
  <pre class="js">
    function myCoolFunction() {
      // stuff goes here...
    }
  </pre>
</aside>

which is rendered as:

Example of an example

1.3.8 External Includes📝 Edit

Including external content into ReSpec is done using the data-include attribute, which points to a URL.

Example 12: Including external content
<section data-include="some.html"></section>

You can specify data-include-format='text' to include content as text, and therefore only process it as much as text is expected to be. The only recognized value are "text", "markdown", and "html" (default).

Note

Note: data-include relies on the browser's ability to retrieve the resource and is governed by CORS (and the browser's security model in general). Browsers will generally block cross origin request, which means file:// URLs will likely fail. For more information, please see "Cross-Origin Resource Sharing (CORS)". You can usually get around this by starting a local web server (e.g., by running python -m http.server 8000 from the command line).

Use data-oninclude to perform transformation on content included with data-include.

1.3.9 Conformance section📝 Edit

ReSpec specifications are RFC2119/RFC8174 keyword aware.

Adding a <section id="conformance"> tells ReSpec that the specification is dealing with "normative" statements. ReSpec can then warn if RFC2119 keywords are accidentally used in informative/non-normative contexts.

Example 13: Using RFC2119 keywords
<section>
  <h2>Requirements</h2>
  <p>A user agent MUST do something.</p>
</section>
<section id="conformance"></section>

Renders as:

Screenshot of RFC2119 usage

1.3.10 Abbreviations📝 Edit

Mark abbreviations using <abbr title="abbreviation">abbr</abbr>. ReSpec will then wrap all matching instances abbreviations with <abbr>.

<p>
 The <abbr title="World Wide Web">WWW</abbr>.
</p>
<p>
 ReSpec will automatically wrap this WWW in an abbr.
</p>

1.3.11 Inline Code📝 Edit

To mark some text as code, use <code> or backticks (`).

1.3.12 Definitions and linking📝 Edit

To define a term, simple wrap it in a <dfn> element.

<dfn>some concept</dfn>

Then, to link to it, just do:

<a>some concept</a>

or 

[=some concept=]

1.3.13 Automatic pluralization📝 Edit

For simple/single nouns, ReSpec handles pluralization automatically:

<dfn>banana</dfn>
<!-- these are the same -->
These [=bananas=] are better than those <a>bananas</a>

1.3.14 Aliases and synonyms📝 Edit

Sometimes a defined terms needs additional related terms or synonyms. In those cases, you can use the data-lt attribute on the dfn element:

<dfn
  data-lt="the best fruit|yellow delicious">
  banana
</dfn>
Note

Note: "lt" stands for "linked term".

The following all link back to "banana":

<p>[=the best fruit=] or the [=yellow delicious=].</p>
Referencing terms from other specifications📝 Edit

The powerful (xref) feature let's you reference terms and concepts in other specifications. For example, to reference "default toJSON steps" from the WebIDL standard:

Example 14: Referencing definitions from other specifications.
<script>
  var respecConfig = {
    xref: ["WebIDL"],
  };
</script>
<a>default toJSON steps</a>

To search for terms + specs your can link to, you can use the XREF UI at http://respec.org/xref/. Below is a screenshot of what the UI looks like:

Screenshot of the XREF search interface
Linking shorthands📝 Edit

There are two important shorthands for linking to definitions:

  • [=term=] for linking regular concepts,
  • {{IdlThing}} for linking WebIDL.

Shorthand syntax works for referencing external terms as well as locally defined terms. It's best practice is to use shorthands all the time.

Example 15: Linking using shorthands.
<script>
  var respecConfig = {
    xref: ["webidl", "payment-request"],
  };
</script>
<section>
  <!--
    Here, we reference the "default toJSON steps" concept defined in [[WebIDL]] standard,
      and the PaymentRequest interface (WebIDL) defined in [[payment-request]] standard.
  -->
  <p>[=default toJSON steps=] for the {{PaymentRequest}} interface are ...</p>

  <!-- We also define a concept "feline", and an interface "Cat". -->
  <p>A <dfn>feline</dfn> has 4 legs and makes sound.</p>
  <pre class="idl">
  interface Cat {}
  </pre>

  <!-- ...and we can reference them as: -->
  <p>A {{Cat}} is a [=feline=] if it meows.</p>
</section>

Read more about linking and other shorthands in the Shorthands Guide.

1.3.15 References📝 Edit

To reference another specification use the [[SPEC-ID]] syntax, where SPEC-ID is the referenced specification's in the Specref ecosystem - which includes most W3C, WHATWG, ECMA, and IETF documents.

When you reference a specification, your document automatically gets a bibliography section.

Example 16: Reference to HTML spec
The [^link^] element is defined in the [[HTML]] spec. 

Which renders as:

Screenshot to text above and automatically generated References section

If you would like to reference a specification by its full name, you can use the three square brackets to "expand it":

<p>
  The [^link^] element is defined in the [[[HTML]]].
</p>

Renders as:

The link element is defined in the HTML Standard.
Normative VS informative references📝 Edit

ReSpec uses the context of the reference to work out if the reference is normative or informative: if the reference is in a section marked "informative", or an example, note, or figure, then ReSpec automatically makes the reference non-normative. Otherwise, the reference is treated as normative.

If you need a non-normative reference in a normative section, you can use a ? like so:

Example 17: Non-normative reference in a normative section
This is normative and MUST be followed. But, sometimes we need a non-normative
example reference [[?FOO]].

1.3.16 Escaping references📝 Edit

To escape a reference, use a backslash "[[\". For example, "[[\InternalSlot]]".

1.3.17 Adding missing references📝 Edit

If a reference is missing, please submit it to Specref. This helps the whole community.

If that is not possible, you can use of the localBiblio configuration option to define your own references.

1.3.19 Custom Styles📝 Edit

If you wish to add your own additional styles to your document, just use the regular <link> and <style> elements.

1.3.20 Advanced: Specifying Configuration via URL📝 Edit

Some of ReSpec's configuration options can be specified in the query string, and they override the options specified in the source. For example, you can override the subtitle by, for example, doing the following: index.html?subtitle=This is a subtitle.

This is useful for quickly overriding configuration options without needing to directly edit the document itself (e.g., for the purpose of exporting a document draft with a different specStatus).

1.4 W3C Documents📝 Edit

ReSpec provides useful options to handle the creation of the W3C boilerplate that goes into the "status of this document" and other key sections.

1.4.1 Short name📝 Edit

Specifications typically require having a "short name", which is the name used (amongst other places) in the canonical "https://w3.org/TR/short-name/" URLs. This is specified using the shortName option, as seen in the example above.

1.4.2 Working Group Information📝 Edit

The group configuration option lets you state to which working/business/community group your specification belongs to. The list of group identifiers can be found at: https://respec.org/w3c/groups/.

Setting the group option sets the IPR Policy for your document, which is reflected in the "Status of this Document" section.

1.4.3 Non-Recommendation track docs📝 Edit

If your document is not intended to be on the W3C Recommendation Track, set noRecTrack to true.

1.4.4 Specification Status📝 Edit

The specStatus option denotes the status of your document, per the W3C Recommendation track. Typically, a status has implications in terms of what other options required. For instance, a document that is intended to become a Recommendation will require previousPublishDate and previousMaturity.

The specStatus section list all the possible status values.

1.4.5 Copyrights & Patents📝 Edit

By default, W3C specifications all get the regular W3C copyright notice. In some cases however, you will want to modify that.

For all document types, you can add your own copyright by using <p class="copyright">.

At times, the patent situation of a specification may warrant being documented beyond the usual boilerplate. In such cases, simply add your own <p> to the Status of this Document section.

1.5 WebIDL Guide📝 Edit

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

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

Ideal linking setup📝 Edit

The recommended way to code up your WebIDL is as follows:

Example 19: WebIDL definitions and linking.
<section data-dfn-for="ExampleInterface">
  <h2><dfn>ExampleInterface</dfn> interface</h2>
  <pre class="idl">
  interface ExampleInterface {
    void exampleMethod();
    readonly attribute USVString url;
  };
  </pre>
  <section>
    <h2><dfn>exampleMethod()</dfn> method</h2>
    <p>The {{ExampleInterface/exampleMethod()}} method steps are:</p>
    <ol class="algorithm">
      <li>Let |x| be ...</li>
    </ol>
  </section>
  <section>
    <h2><dfn>url</dfn> attribute</h2>
    <p>The {{ExampleInterface/url}} attribute...</p>
  </section>
</section>
<section>
 <h2>Here is how you link!</h2>
 <p>
  The {{ExampleInterface}} 
  or the {{ExampleInterface/exampleMethod()}} method
  or the {{ExampleInterface/url}} attribute.
 </p>
</section>

Defining the interface📝 Edit

Given interface Request {};, you can define the interface inside a heading like so:

Example 20: Defining WebIDL interfaces.
<section>
  <h2><dfn>Request</dfn> interface</h2>
  <pre class="idl">
    interface Request {};
  </pre>
  <p>An instance of {{Request}} allows you to make a request.</p>
</section>

The above provides convenient linking to the section where the interface is defined.

Using data-dfn-for📝 Edit

When defining things, the data-dfn-for creates child-parent relationships (e.g., a .method() is "for", or part of, SomeInterface).

For example, the following defines both the url and the clone method.

Example 21: Using data-dfn-for.
<section data-dfn-for="Request">
  <h2>`Request` interface</h2>
  <pre>
  interface Request {
    readonly attribute ByteString method;
    readonly attribute USVString url;
  };
  </pre>
  <p>The <dfn>clone()</dfn> method. The <dfn>url</dfn> attribute.</p>
  <p>
    Links to {{Request/clone()}} method. Links to the {{Request/url}} attribute.
  </p>
</section>

Multiple interfaces with same attributes/methods📝 Edit

If, for instance, you have two interfaces with methods or attributes that are the same:

Example 22: Multiple interfaces with same attributes/methods.
<pre class="idl">
interface Request {
  readonly attribute USVString url;
};
interface Response {
  readonly attribute USVString url;
};
</pre>

You explicitly distinguish between them like so:

Example 23: Distinguishing between multiple interfaces with same attributes/nodes.
<section data-dfn-for="Request">
  <p>
    The <dfn>url</dfn> attribute of {{Request}} is used by {{Response/url}}.
  </p>
</section>

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

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 24: 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 25: 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 26: 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
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 27: 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 28: 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 29: Headings become sections
## Introduction

Some text.

### Background

More text.

Custom heading IDs📝 Edit

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

Figures📝 Edit

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

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

Code blocks📝 Edit

Use triple-backtick fences with a language hint:

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

For WebIDL blocks:

Example 33: 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 34: 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 36: 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 37: Browser support table for payment-request
var respecConfig = {
  caniuse: "payment-request",
};

With options📝 Edit

Example 38: 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
maxAge number 86400000 Cache duration in milliseconds (default: 24 hours). Set to 0 for fresh data on every load.

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 39: 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 40: 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 41: 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 42: 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 43: Set GitHub repository (shortest form)
var respecConfig = {
  github: "w3c/payment-request",
};
Example 44: Set GitHub repository as full URL
var respecConfig = {
  github: "https://github.com/w3c/payment-request",
};

With options📝 Edit

Example 45: Non-default branch
var respecConfig = {
  github: {
    repoURL: "https://github.com/w3c/payment-request",
    branch: "main",
  },
};
Example 46: 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: false

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

Basic usage📝 Edit

Example 47: Enable variable highlighting
var respecConfig = {
  highlightVars: true,
};
  • Variables must be marked up with <var> elements: Let <var>request</var> be a new request.
  • Highlighting is scoped to the nearest enclosing <ol> algorithm step list
  • The |variable| shorthand in Markdown mode 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 48: 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 49: Use the default W3C license (usually no need to set this)
var respecConfig = {
  // w3c-software-doc is already the default for W3C documents
};
Example 50: 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 51: 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 52: Disable linter entirely
var respecConfig = {
  lint: false,
};

5.12.3 Enable or disable individual rules📝 Edit

Example 53: 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-punctuation false Missing punctuation at end of paragraphs
informative-dfn false Definitions in informative sections
local-refs-exist true Local #fragment links that don't resolve
no-captionless-tables true Tables without a <caption>
no-headingless-sections true Sections without a heading
no-http-props true Non-HTTPS URLs in config
no-link-warnings false Suppress all link warnings
no-unused-dfns false Defined terms never referenced
no-unused-vars false WebIDL variables never used
privsec-section false Missing Privacy and Security Considerations section
wpt-tests-exist false data-tests attributes pointing to non-existent WPT tests

5.12.5 Suppress a single violation inline📝 Edit

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

Example 54: 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 on the document using axe-core. Reports accessibility violations as ReSpec warnings.

How to enable📝 Edit
Example 55: Run all default accessibility rules
var respecConfig = {
  lint: {
    a11y: true,
  },
};
Example 56: Run only specific rules
var respecConfig = {
  lint: {
    a11y: {
      runOnly: ["image-alt", "link-name"],
    },
  },
};
Example 57: Enable slow rules, disable others
var respecConfig = {
  lint: {
    a11y: {
      rules: {
        "color-contrast": { enabled: true },  // slow, disabled by default
        "image-alt": { enabled: false },
      },
    },
  },
};
Quick enable via URL📝 Edit

Add ?a11y=true to the URL to temporarily enable all a11y rules without changing config.

  • Powered by axe-core — see the axe options documentation for full configuration options
  • Some rules (like color-contrast) are slow and disabled by default — enable them only when needed
  • Running on hosted documents (GitHub Pages) may slow rendering — enable selectively
  • Violations appear as yellow warnings in the ReSpec pill counter
How to disable📝 Edit
Example 58: 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 59: Enable check-punctuation
var respecConfig = {
  lint: {
    "check-punctuation": true,
  },
};
How to disable📝 Edit
Example 60: 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 61: 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 62: 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 63: 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 64: 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 65: 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 66: 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 67: 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 68: 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 69: Enable no-unused-vars rule
var respecConfig = {
  lint: { "no-unused-vars": true },
};
Suppress for one variable📝 Edit
Example 70: 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 71: 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 72: Enable privsec-section rule
var respecConfig = {
  lint: { "privsec-section": true },
};
How to disable📝 Edit
Example 73: 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 74: 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 75: 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 77: 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 78: 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 79: Enable MDN annotations using shortName as key
var respecConfig = {
  shortName: "payment-request",
  mdn: true,
};
Example 80: Enable MDN annotations with explicit key
var respecConfig = {
  mdn: "payment-request",
};

With options📝 Edit

Example 81: 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 82: 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 83: Use your own payment pointer
var respecConfig = {
  monetization: "$wallet.example.com/my-wallet",
};
Example 84: Disable monetization entirely
var respecConfig = {
  monetization: false,
};
Example 85: 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 86: 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 88: Pluralization is on by default
var respecConfig = {
  // pluralize: true is already the default for W3C specs
};

How it works📝 Edit

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

<!-- Both of these link correctly: -->
<a>user agent</a>
<a>user agents</a>
Example 90: 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 91: 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 make final modifications to the generated document, add custom markup, or run validation.

Example 92: Add a custom paragraph after processing
function addBuildInfo(config, document) {
  const p = document.createElement("p");
  p.textContent = `Built on ${new Date().toDateString()}.`;
  document.querySelector("#sotd").append(p);
}

var respecConfig = {
  postProcess: [addBuildInfo],
};
Example 93: Async post-processing
async function addVersionBadges(config, document) {
  const links = document.querySelectorAll("a[data-needs-version]");
  for (const link of links) {
    const version = await fetchVersion(link.dataset.needsVersion);
    link.textContent = `v${version}`;
  }
}

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

Function signature📝 Edit

Each function receives three arguments:

Argument Type Description
config Object The respecConfig object (plus internal ReSpec state)
document Document The fully-processed ReSpec document
utils Object ReSpec utility functions (e.g. for showing errors)
  • Functions run in order, awaiting async functions before proceeding
  • At this point, all headings, ToC, dfn panels, links, and boilerplate are already generated
  • Changes made in postProcess appear in both the live preview and the saved HTML export
  • For pre-processing before ReSpec starts, see preProcess
  • To be notified when ALL processing (including postProcess) is done, use respecIsReady

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, modify the DOM before ReSpec sees it, or set up configuration that depends on async operations.

Example 94: Fetch data before processing begins
async function loadFeatureData(config, document) {
  const res = await fetch("/api/features.json");
  const data = await res.json();
  // Make data available to the spec
  window.featureData = data;
}

var respecConfig = {
  preProcess: [loadFeatureData],
};
Example 95: Modify the DOM before ReSpec processes it
function addDynamicSection(config, document) {
  const section = document.createElement("section");
  section.innerHTML = `<h2>Generated on</h2><p>${new Date().toDateString()}</p>`;
  document.body.append(section);
}

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

Function signature📝 Edit

Each function receives three arguments:

Argument Type Description
config Object The respecConfig object (plus internal ReSpec state)
document Document The HTML document in its original, unprocessed form
utils Object ReSpec utility functions (e.g. for showing errors)
  • Functions run in order, and ReSpec awaits each one before running the next
  • async functions are fully supported
  • preProcess runs before structure, definitions, xref, and all other ReSpec processing
  • 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 96: 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 97: 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 98: Editor's Draft (active development)
var respecConfig = {
  specStatus: "ED",
};
Example 99: 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

5.27 subjectPrefix📝 Edit

If you wish feedback to your mailing list about this specific document to have a specific prefix subject in its subject line, then specify this (including the [ and ] if you want them). The various of the heading matter that refer to the mailing list will use this information.

Example 100: Add a prefix for mailing list subjects.
var respecConfig = {
  subjectPrefix: "[Foopy-Spec-Feedback]",
};

5.28 subtitle📝 Edit

Type: string Default: ""

A subtitle shown below the document title in the header.

Basic usage📝 Edit

Example 101: 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

The URL of your test suite, gets included in the specification's headers.

Example 102: Add a test suite URL to be included in page header.
var respecConfig = {
  testSuiteURI: "https://example.com/test/suite/",
};

Also see: wpt-tests-exist lint rule.

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 103: Enable xref with web-platform profile
var respecConfig = {
  xref: "web-platform",
};

Then write terms naturally — ReSpec links them automatically:

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

Configuration forms📝 Edit

Boolean📝 Edit
Example 105: Enable xref (minimal)
var respecConfig = {
  xref: true,
};
Profile name📝 Edit
Example 106: 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 107: Limit xref to specific specs
var respecConfig = {
  xref: ["FETCH", "DOM"],
};
Object (advanced)📝 Edit
Example 108: 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)
  • When both profile and specs are set, both sets of specs are used for disambiguation
  • To manually cite a specific spec for a term, use data-cite on the element
  • Browse and test xref lookups at respec.org/xref
  • If a term isn't found, ask the defining spec's editors to export it with data-export
  • See Auto-linking external references for detailed usage

6. W3C Specific Configuration Options

6.1 additionalCopyrightHolders📝 Edit

For regular documents, this is used to specify that additional parties hold a copyright jointly with W3C on this document. This is typically used when publishing documents that were developed in cooperation with other friendly standard consortia such as the IETF.

The option is simply some text giving the additional copyright holders. For unofficial documents, this string is used to replace the default CC license.

You can preview this feature in live examples:

6.2 alternateFormats📝 Edit

Shows links to alternate formats (such as PDF, ePub) in the document header.

This option accepts an array of objects, each of which has two required fields:

uri
for the link to the alternate document
label
for a human readable string that matches it. This is used to link to alternate formats for the same content (e.g. PDF, ePub, PS).

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 111: Point canonical to TR/ location
var respecConfig = {
  shortName: "payment-request",
  canonicalURI: "TR",
};
Example 112: Point canonical to Editor's Draft
var respecConfig = {
  canonicalURI: "edDraft",
};
Example 113: 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

This configuration option must be specified for Interest Group Notes (IG-NOTE), where it must point at the disclosure section of the group charter, per publication rules. This option is ignored for all other documents.

Example 114: Add charter disclosure URL for IG-NOTE.
var respecConfig = {
  charterDisclosureURI: "https://www.w3.org/2019/06/me-ig-charter.html#patentpolicy",
};

6.5 copyrightStart📝 Edit

ReSpec knows to include a copyright year that matches the publishDate in the copyright notice. However, for documents developed over a period of several years it is preferable to indicate the first year during which the copyright started by setting this option.

Note that this can always be safely specified since if copyrightStart is the same as the publishDate's year it is ignored.

The following appears as "Copyright © 1977-2016".

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 116: 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 117: 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

An URL to a document capturing errata for the specification. Generally, this only applies to documents with a "REC" and "PER" specStatus.

Example 118: Add URL to errata.
var respecConfig = {
  status: "REC",
  errata: "https://www.w3.org/XML/xml-V10-5e-errata",
};

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 119: Associate with a Working Group
var respecConfig = {
  group: "webapps",
};
Example 120: Multiple groups (joint deliverable)
var respecConfig = {
  group: ["webapps", "css"],
};
Example 121: Disambiguate group type
var respecConfig = {
  group: "wg/wot",  // "wg/", "cg/", "ig/", or "bg/" prefix
};
  • 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

The URL of the implementation report (documenting how your test suite fares with implementations). It gets included in the specification's headers.

Example 122: Add URL of the implementation report.
var respecConfig = {
  implementationReportURI: "https://example.com/imp-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 123: 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

"Leveled" specs are generally specs that build on each other in a backwards compatible way. They generally include the text from each previous level. This is used a lot by the W3C's CSS Working Group.

Note

Note: Refrain using a level unless you've considered all the implications of doing so. Levels can be very hard to maintain, specially if levels are evolving concurrently.

The level configuration options automatically appends the level to your spec’s title and shortName. The level is an integer value greater than or equal to 0.

Example 124: Set the current specification to level 2.
var respecConfig = {
  level: 2,
  shortName: "payment-request",
};

Which results in:

Which would render as, for example:

Screenshot 2020-02-21 18 54 02

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 125: 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 126: 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

Sometimes it happens that a document is moved in the version control system, passed from one group to another, or split into several smaller documents. In such cases since the version control information is harder to find, this option can be used to point to a previous Editor's Draft. Rarely used.

Example 127: Specify URL to previous editor's draft.
var respecConfig = {
  prevED: "https://example.com/old/ed",
};

6.16 previousDiffURI📝 Edit

When producing a diff-marked version, ReSpec uses the previousURI as the old version by default. Use this configuration option if you wish to override this to a specific URL.

Example 128: Specify the previous URL for diff generation.
var respecConfig = {
  previousURI: "https://www.w3.org/TR/2014/WD-FOO-20140327/",
  // Diff against the first version instead
  previousDiffURI: "https://www.w3.org/TR/2014/WD-FOO-20130101/",
};

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 129: 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 130: 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

If you are working on a new version of an existing Recommendation, use this to indicate what its shortName was.

Example 131: Set shortName for previous version of recommendation.
var respecConfig = {
  shortName: "fancy-feature-l2",
  prevRecShortname: "fancy-feature",
};

6.20 prevRecURI📝 Edit

If you are working on a new version of an existing Recommendation, use this to indicate what its URL was.

If a prevRecURI is not specified but prevRecShortname is, the latter will be used to generate the former by prefixing "https://www.w3.org/TR/" to it. Note however that while in the overwhelming majority of cases this works, it is not recommended to use this approach since if the Recommendation is later Rescinded, the link will be stale. Instead, use the dated link to the Recommendation.

Example 132: Set URL of previous version of Recommendation.
var respecConfig = {
  prevRecURI: "https://www.w3.org/TR/2014/example-20140327/",
};

6.21 submissionCommentNumber📝 Edit

Allows W3C staff to link to a comment number.

Which shows up as:

<a href="https://www.w3.org/Submission/2018/03/Comment/">
  W3C Team Comment
</a>

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

Example 135: 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>
  • 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

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 136: Contributors section
<section>
  <h2>Contributors</h2>
  <p>We thank the following contributors:</p>
  <ul id="gh-contributors"></ul>
</section>
Example 137: 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 138: IDL index appendix
<section id="idl-index" class="appendix">
  <!-- All WebIDL from across the document appears here -->
</section>
Example 139: 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>
  • Collects every <pre class="idl"> block in the document and combines them
  • If the spec has no WebIDL, the section still appears with a note saying there's no IDL
  • Add custom content (heading, intro paragraph) before the IDL — ReSpec appends the IDL after it
  • Typically placed as an informative appendix

7.4 index📝 Edit

Adding a <section id="index"> in your document instructs ReSpec to gather all the terms defined in your specification, as well as all the terms referenced by your specification into a single section. The index lets you conveniently search for all defined/referenced terms, as well as find their usage in the document.

Example 140: Index of locally defined and externally referenced terms.
<section id="index" class="appendix">
  <!-- All the terms will magically appear here -->
</section>

You can also add a custom header and content to your index:

Example 141: Terms index with custom header and content.
<section id="index" class="appendix">
  <h2>List All The Terms!</h2>
  <p>Wow, that's a lot of terms!</p>
  <!-- All the terms will magically appear here -->
</section>

If you'd lie to show the full spec/document's title in the index, you can add the special "prefer-full-spec-title" CSS class, like so:

<section class="prefer-full-spec-title appendix" id="index">

So, for example, instead of "[DOM]", the document will show "DOM Standard" in the index.

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

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

Example 142: 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 references📝 Edit

You can add an explicit <section id="reference"> in cases where you need to add custom content to the references section of a document.

Example 143: List of normative and non-normative citations.
<section id="references">
  <p>Citations are great!</p>
  <!-- normative and informative references will appear below -->
</section>

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 144: Table of Figures section
<section id="tof">
  <!-- ReSpec generates the list of figures here -->
</section>
  • All <figure> elements with a <figcaption> and an id are included
  • 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 145: 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 146: 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 — tables without captions trigger the no-captionless-tables linting rule
  • Empty links to a figure's id auto-populate with "Figure N"
  • 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 147: 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 148: Auto-detected syntax highlighting
<pre>
function fetch(url) {
  return new Promise(resolve => {
    // ... JS is auto-detected
  });
}
</pre>
Example 149: 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 150: Disable for a specific block
<pre class="nohighlight">
pseudocode or plain text here
</pre>

Load additional languages📝 Edit

Example 151: 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 152: A basic section
<section>
  <h2>The <code>fetch()</code> method</h2>
  <p>The <code>fetch()</code> method initiates a network request.</p>
</section>
Example 153: 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 154: 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 155: 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 156: 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 157: Editor's note about a pending issue
<p class="ednote">
  This section needs to be revised to address the i18n WG feedback.
</p>
Example 158: 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 159: Code example
<pre class="example">
  const result = navigator.credentials.get({ password: true });
</pre>
Example 160: 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 161: Counter-example (illegal usage)
<pre class="illegal-example">
  document.write("&lt;!-- don't do this -->");
</pre>
  • Examples are numbered automatically ("Example 1", "Example 2", …)
  • 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

The exclude CSS class allows HTML tags to opt-out of being processed by ReSpec.

It is only supported on the following elements:

Some examples of usage:

Example 162: Excluding things
<p>
 <abbr class="exclude" title="Ay-Bee-See">ABC</abbr>,
 but this won't be wrapped ABC.
</p>

<aside class="example" title="A hypothetical API">
  <pre class="idl exclude">
    interface ItsTwentyTwenty {
      undefined cantSeeNobody();
    };
  </pre>
</aside>

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 163: 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 164: Export using class syntax
<dfn class="export">request</dfn>

Prevent export📝 Edit

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

9.6 .informative📝 Edit

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

Example 166: 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 167: Inline issue note
<div class="issue">
  <p>We need to decide whether this should be synchronous.</p>
</div>
Example 168: Embed a GitHub issue by number
<div class="issue" data-number="363"></div>
Example 169: Issue with a title
<p class="issue" title="Needs resolution">
  Should this be normative?
</p>
  • When data-number is set and github is configured, ReSpec downloads the issue content from GitHub and embeds it
  • The title attribute is interpreted as HTML — see title attributes
  • 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 170: 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 173: 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 175: 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 176: 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
  • Works on block elements: <div>, <p>, <aside>, <section>
  • 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 177: 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 178: 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 179: 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

Warning: only use this as a last resort. This feature is not recommended.

The override css class allow spec editors to completely override a section that would normally be dynamically filled with ReSpec generated content.

Sections you can override include:

Example 180: Completely override the content of 'Status of this Document' section.
<section id="sotd" class="override">
  <h2>Status of this document</h2>
  <p>Exploring new ideas...</p>
</section>

9.16 permission📝 Edit

The permission class is used to define a browser permission.

Example 181: Using permission on a 'dfn' element
<p>
  The Geolocation API is a default powerful feature identified by the
  name `<dfn class="permission">"geolocation"</dfn>`.
</p>

9.17 practice📝 Edit

A <div> containing a best practice description.

<div class="practice">
  <p class="practicedesc">
    <span class="practicelab">Best practice</span>
    Practice makes perfect, but perfect is the enemy of the good.
  </p>
</div>

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

If you want to include content that is used during the generation of the specification but must be removed from the output, then add the remove class to it. That is used for instance for all the script elements that pull in ReSpec and define its configuration.

Example 182: Remove some content once ReSpec has finished processing.
<div class="remove">
  <p>This will be removed at build time.</p>
</div>

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 183: Content removed at export time
<div class="removeOnSave">
  <p class="ednote">Remember to update the SotD before publication.</p>
</div>
Example 184: 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 updateable-rec📝 Edit

For W3C Proposed Recommendations, declaring class="updateable-rec" on the Status of This Document <section> indicates the specification intends to allow new features once it becomes a W3C Recommendation. This will include the appropriate boilerplate text for you.

Example 185: using updateable-rec
<section id="sotd" class="updateable-rec">
  <p>Other status related stuff here...</p>
</section>

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 186: Auto-generate abbreviation
<dfn data-abbr>user agent</dfn>
<!-- Renders as: user agent (UA) -->
Example 187: 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
  • Only affects the first occurrence of the definition — subsequent <a> links are not automatically given the <abbr> treatment

10.2 data-cite📝 Edit

Applies to: <a>, <dfn>

Manually links an element to a specific term or section in another specification. Use this when xref automatic linking doesn't work or when you need to link to a specific fragment.

Note

Note: Prefer automatic xref linking where possible. data-cite is for cases where the term isn't in the xref database or when you need a precise anchor.

Syntax📝 Edit

data-cite="SPEC-ID[/path-to-doc]#fragment"
  • SPEC-ID — the spec's shortname from SpecRef (e.g. "FETCH", "HTML")
  • /path-to-doc — optional sub-path within a multi-page spec
  • #fragment — the anchor ID in the target document

Prefix with ! to make the citation normative: data-cite="!FETCH#concept-fetch"

Example 189: Normative citation
<a data-cite="!FETCH#concept-request">request</a>
Example 190: Define a term as being defined in another spec
<dfn data-cite="DOM#concept-event">event</dfn>
Example 192: Multi-page spec with path
<a data-cite="HTML/webappapis.html#event-loop">event loop</a>
  • Using data-cite="SPEC" without a #fragment links to the spec itself and adds it to the bibliography
  • Using data-cite="SPEC#fragment" links to the exact anchor — the element's text becomes the link text
  • To link to a heading in another spec, use the heading's ID as the fragment
  • You can browse spec shortnames and fragments at respec.org/xref or specref.org

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 193: 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 194: 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 195: Explicit type for an abstract operation
<p>To <dfn data-dfn-type="abstract-op">process a widget</dfn>, run these steps:</p>
Example 196: 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 197: 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 198: Include an HTML file
<section data-include="sections/introduction.html"></section>
Example 199: Include a Markdown file
<section data-include="sections/api.md"
         data-include-format="markdown"></section>
Example 200: 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 201: Include plain text
<section data-include="changelog.txt"
         data-include-format="text"></section>
Example 202: 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 203: 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 204: Default: content inserted inside element
<section data-include="content.html">
  <!-- content.html's markup is placed here, inside the <section> -->
</section>
Example 205: 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 208: 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 209: 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 212: 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 213: 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 214: 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 215: 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 216: 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 217: 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 218: Sort a list ascending (A to Z)
<ul data-sort>
  <li>Banana</li>
  <li>Apple</li>
  <li>Cherry</li>
</ul>
Example 219: 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 221: Variable with explicit type
<p>Let <var data-type="Request">request</var> be a new request.</p>

The |variable:Type| shorthand is equivalent:

Example 222: 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 223: 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 224: 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 225: Changes since a tag
<p>Changes since the CR snapshot:</p>
<rs-changelog from="CR"></rs-changelog>
Example 226: Changes between two points
<rs-changelog from="v1.0" to="v2.0"></rs-changelog>
Example 227: Monorepo — filter to a specific path
<rs-changelog from="CR" path="payment-request/index.html"></rs-changelog>
Example 228: 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, access errors/warnings, or export the processed HTML.

document.respec.isReady📝 Edit

A Promise that resolves when ReSpec finishes all processing.

Example 229: Wait for ReSpec to finish
<script>
  document.addEventListener("DOMContentLoaded", async () => {
    await document.respec.isReady;
    console.log("ReSpec done!", document.respec.errors);
  });
</script>

document.respec.errors📝 Edit

An array of errors found during processing. Each item has:

Property Type Description
message string Error message text
plugin string Name of the ReSpec plugin that generated the error
hint string Optional hint for how to fix the error

document.respec.warnings📝 Edit

Same structure as errors, but for warnings.

document.respec.toHTML()📝 Edit

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

Example 230: Get processed HTML as a string
<script>
  document.addEventListener("DOMContentLoaded", async () => {
    const html = await document.respec.toHTML();
    console.log("Processed HTML length:", html.length);
  });
</script>
  • All properties are available immediately when ReSpec loads — use isReady before reading errors/warnings since they may not be populated yet
  • The deprecated document.respecIsReady was a Promise directly on document — the modern document.respec.isReady is preferred

13. Deprecated Options

13.1 addPatentNote (Deprecated)📝 Edit

This is no longer supported by ReSpec. Please write any patent-related notes directly into the "Status of This Document" section instead.

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

Warning: This is deprecated and has been removed. Use the .notoc CSS class instead.

A boolean, which when set to true, will cause the introductory sections to also show up in the table of contents. This is rarely needed, but some groups prefer to have it.

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 231: 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 232: 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 233: 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 234: 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 235: 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 236: 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