diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 0c8301f3..ce54f976 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -142,6 +142,28 @@ jobs:
name: spec-artifact
path: spec.tar.gz
+ htmlcheck:
+ name: "🔎 Validate generated HTML"
+ runs-on: ubuntu-latest
+ needs: [build-spec]
+ steps:
+ - name: "📥 Source checkout"
+ uses: actions/checkout@v2
+
+ - name: "📥 Fetch built spec"
+ uses: actions/download-artifact@v2
+ with:
+ name: spec-artifact
+
+ - name: "📝 Unpack the spec"
+ run: |
+ tar -xvzf spec.tar.gz
+
+ - name: "Run htmltest"
+ uses: wjdp/htmltest-action@master
+ with:
+ config: .htmltest.yaml
+
build-historical-spec:
name: "📖 Build the historical backup spec"
runs-on: ubuntu-latest
diff --git a/.htmltest.yaml b/.htmltest.yaml
new file mode 100644
index 00000000..1563408b
--- /dev/null
+++ b/.htmltest.yaml
@@ -0,0 +1,6 @@
+# config file for htmltest. This is used by one of the checks in Github
+# Actions.
+
+IgnoreDirectoryMissingTrailingSlash: true
+DirectoryPath: spec
+CheckExternal: false
diff --git a/changelogs/internal/newsfragments/1329.clarification b/changelogs/internal/newsfragments/1329.clarification
new file mode 100644
index 00000000..c5b60e24
--- /dev/null
+++ b/changelogs/internal/newsfragments/1329.clarification
@@ -0,0 +1 @@
+Use a link checker to ensure that we do not have broken links.
diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md
index f701aff8..78e1ef29 100644
--- a/content/client-server-api/modules/end_to_end_encryption.md
+++ b/content/client-server-api/modules/end_to_end_encryption.md
@@ -180,7 +180,7 @@ process:
the resulting list of devices in persistent storage, and clears the
'outdated' flag.
3. During its normal processing of responses to [`/sync`](/client-server-api/#get_matrixclientv3sync), Alice's client
- inspects the `changed` property of the [`device_lists`](/client-server-api/#extensions-to-sync-1) field. If it
+ inspects the `changed` property of the [`device_lists`](#e2e-extensions-to-sync) field. If it
is tracking the device lists of any of the listed users, then it
marks the device lists for those users outdated, and initiates
another request to [`/keys/query`](/client-server-api/#post_matrixclientv3keysquery) for them.
@@ -1614,7 +1614,7 @@ When a client is updating a Megolm session (room key) in its store, the client M
{{% http-api spec="client-server" api="keys" %}}
-##### Extensions to /sync
+##### Extensions to /sync
This module adds an optional `device_lists` property to the [`/sync`](/client-server-api/#get_matrixclientv3sync) response,
as specified below. The server need only populate this property for an
diff --git a/content/client-server-api/modules/spaces.md b/content/client-server-api/modules/spaces.md
index 797e800c..cf192a69 100644
--- a/content/client-server-api/modules/spaces.md
+++ b/content/client-server-api/modules/spaces.md
@@ -99,7 +99,7 @@ relevant state event, such as through redaction or otherwise clearing the `conte
{{% event event="m.space.child" %}}
-###### Ordering
+###### Ordering of children within a space
When the client is displaying the children of a space, the children should be ordered
using the algorithm below. In some cases, like a traditional left side room list, the
diff --git a/content/server-server-api.md b/content/server-server-api.md
index 2a034c35..7b33a956 100644
--- a/content/server-server-api.md
+++ b/content/server-server-api.md
@@ -853,7 +853,7 @@ on the resulting `m.room.member` event.
If the joining server fails all conditions then a 403 `M_FORBIDDEN` error
is used by the resident server.
-## Knocking upon a room
+## Knocking upon a room
Rooms can permit knocking through the join rules, and if permitted this
gives users a way to request to join (be invited) to the room. Users who
diff --git a/data/api/client-server/inviting.yaml b/data/api/client-server/inviting.yaml
index c24e5f49..96e3dae2 100644
--- a/data/api/client-server/inviting.yaml
+++ b/data/api/client-server/inviting.yaml
@@ -35,8 +35,8 @@ paths:
description: |-
*Note that there are two forms of this API, which are documented separately.
This version of the API requires that the inviter knows the Matrix
- identifier of the invitee. The other is documented in the*
- [third party invites section](/client-server-api/#post_matrixclientv3roomsroomidinvite-1).
+ identifier of the invitee. The other is documented in the
+ [third party invites](/client-server-api/#third-party-invites) section.*
This API invites a user to participate in a particular room.
They do not start participating in the room until they actually join the
diff --git a/data/api/client-server/sync.yaml b/data/api/client-server/sync.yaml
index 93265cae..dce3c63e 100644
--- a/data/api/client-server/sync.yaml
+++ b/data/api/client-server/sync.yaml
@@ -383,7 +383,7 @@ paths:
type: object
description: |-
Information on end-to-end device updates, as specified in
- [End-to-end encryption](/client-server-api/#extensions-to-sync-1).
+ [End-to-end encryption](/client-server-api/#e2e-extensions-to-sync).
device_one_time_keys_count:
title: One-time keys count
type: object
@@ -391,7 +391,7 @@ paths:
type: integer
description: |-
Information on end-to-end encryption keys, as specified
- in [End-to-end encryption](/client-server-api/#extensions-to-sync-1).
+ in [End-to-end encryption](/client-server-api/#e2e-extensions-to-sync).
required:
- next_batch
examples:
diff --git a/data/event-schemas/schema/m.space.child.yaml b/data/event-schemas/schema/m.space.child.yaml
index afdfefa9..feef0adc 100644
--- a/data/event-schemas/schema/m.space.child.yaml
+++ b/data/event-schemas/schema/m.space.child.yaml
@@ -27,7 +27,7 @@ properties:
`order` values with the wrong type, or otherwise invalid contents, are to be treated
as though the `order` key was not provided.
- See [Ordering](/client-server-api/#ordering-1) for information on how the ordering works.
+ See [Ordering of children within a space](/client-server-api/#ordering-of-children-within-a-space) for information on how the ordering works.
suggested:
type: boolean
description: |-