diff --git a/changelogs/client_server/newsfragments/2387.new b/changelogs/client_server/newsfragments/2387.new
index a709a5fa..cfb5af1c 100644
--- a/changelogs/client_server/newsfragments/2387.new
+++ b/changelogs/client_server/newsfragments/2387.new
@@ -1 +1 @@
-Add key backup (``/room_keys/*``) endpoints.
+Add key backup (`/room_keys/*`) endpoints.
diff --git a/changelogs/client_server/newsfragments/2399.feature b/changelogs/client_server/newsfragments/2399.feature
index e9819639..3b0380b2 100644
--- a/changelogs/client_server/newsfragments/2399.feature
+++ b/changelogs/client_server/newsfragments/2399.feature
@@ -1 +1 @@
-Document how clients can advise recipients that it is withholding decryption keys as per `MSC2399 `_.
\ No newline at end of file
+Document how clients can advise recipients that it is withholding decryption keys as per [MSC2399](https://github.com/matrix-org/matrix-doc/pull/2399).
diff --git a/changelogs/client_server/newsfragments/2536.feature b/changelogs/client_server/newsfragments/2536.feature
index 1006ff52..56e4e79b 100644
--- a/changelogs/client_server/newsfragments/2536.feature
+++ b/changelogs/client_server/newsfragments/2536.feature
@@ -1 +1 @@
-Add cross-signing properties to the response of ``POST /keys/query`` per [MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756).
+Add cross-signing properties to the response of `POST /keys/query` per [MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756).
diff --git a/changelogs/client_server/newsfragments/2536.new b/changelogs/client_server/newsfragments/2536.new
index 88cb6703..8572e33a 100644
--- a/changelogs/client_server/newsfragments/2536.new
+++ b/changelogs/client_server/newsfragments/2536.new
@@ -1 +1 @@
-Add ``POST /keys/device_signing/upload`` and ``POST /keys/signatures/upload`` per [MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756).
+Add `POST /keys/device_signing/upload` and `POST /keys/signatures/upload` per [MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756).
diff --git a/changelogs/client_server/newsfragments/2591.clarification b/changelogs/client_server/newsfragments/2591.clarification
index 7473f453..dadf44ab 100644
--- a/changelogs/client_server/newsfragments/2591.clarification
+++ b/changelogs/client_server/newsfragments/2591.clarification
@@ -1 +1 @@
-Fix issues with ``age`` and ``unsigned`` being shown in the wrong places.
+Fix issues with `age` and `unsigned` being shown in the wrong places.
diff --git a/changelogs/client_server/newsfragments/2609.removal b/changelogs/client_server/newsfragments/2609.removal
index deafc77d..24b523e9 100644
--- a/changelogs/client_server/newsfragments/2609.removal
+++ b/changelogs/client_server/newsfragments/2609.removal
@@ -1 +1 @@
-Remove unimplemented ``m.login.oauth2`` and ``m.login.token`` user-interactive authentication mechanisms.
+Remove unimplemented `m.login.oauth2` and `m.login.token` user-interactive authentication mechanisms.
diff --git a/changelogs/client_server/newsfragments/2629.clarification b/changelogs/client_server/newsfragments/2629.clarification
index 07fc430e..0813de44 100644
--- a/changelogs/client_server/newsfragments/2629.clarification
+++ b/changelogs/client_server/newsfragments/2629.clarification
@@ -1 +1 @@
-Remove ``room_id`` from ``/sync`` examples.
+Remove `room_id` from `/sync` examples.
diff --git a/changelogs/client_server/newsfragments/2647.clarification b/changelogs/client_server/newsfragments/2647.clarification
index a0c5e7cc..e902980e 100644
--- a/changelogs/client_server/newsfragments/2647.clarification
+++ b/changelogs/client_server/newsfragments/2647.clarification
@@ -1 +1 @@
-Improve consistency and clarity of event schema ``title``\ s.
+Improve consistency and clarity of event schema `title` s.
diff --git a/changelogs/client_server/newsfragments/2709.feature b/changelogs/client_server/newsfragments/2709.feature
index a6b3e2a2..309b1c0d 100644
--- a/changelogs/client_server/newsfragments/2709.feature
+++ b/changelogs/client_server/newsfragments/2709.feature
@@ -1 +1 @@
-Add a ``device_id`` parameter to login fallback per `MSC2604 `_.
+Add a `device_id` parameter to login fallback per [MSC2604](https://github.com/matrix-org/matrix-doc/pull/2604).
diff --git a/changelogs/client_server/newsfragments/2754.clarification b/changelogs/client_server/newsfragments/2754.clarification
index d3f96b84..ddbafc87 100644
--- a/changelogs/client_server/newsfragments/2754.clarification
+++ b/changelogs/client_server/newsfragments/2754.clarification
@@ -1 +1 @@
-Clarify the behaviour of ``state`` for ``/sync`` with lazy-loading.
+Clarify the behaviour of `state` for `/sync` with lazy-loading.
diff --git a/changelogs/client_server/newsfragments/2795.feature b/changelogs/client_server/newsfragments/2795.feature
index 62fd9425..85637012 100644
--- a/changelogs/client_server/newsfragments/2795.feature
+++ b/changelogs/client_server/newsfragments/2795.feature
@@ -1 +1 @@
-Added support for ``reason`` on all membership events and related endpoints as per `MSC2367 `_.
+Added support for `reason` on all membership events and related endpoints as per [MSC2367](https://github.com/matrix-org/matrix-doc/pull/2367).
diff --git a/changelogs/client_server/newsfragments/2796.feature b/changelogs/client_server/newsfragments/2796.feature
index 526c061f..067d98d8 100644
--- a/changelogs/client_server/newsfragments/2796.feature
+++ b/changelogs/client_server/newsfragments/2796.feature
@@ -1 +1 @@
-Add a 404 ``M_NOT_FOUND`` error to push rule endpoints as per `MSC2663 `_.
+Add a 404 `M_NOT_FOUND` error to push rule endpoints as per [MSC2663](https://github.com/matrix-org/matrix-doc/pull/2663).
diff --git a/changelogs/client_server/newsfragments/2807.feature b/changelogs/client_server/newsfragments/2807.feature
index e011cde6..6a34b60f 100644
--- a/changelogs/client_server/newsfragments/2807.feature
+++ b/changelogs/client_server/newsfragments/2807.feature
@@ -1 +1 @@
-Make ``reason`` and ``score`` parameters optional in the content reporting API (MSC2414).
+Make `reason` and `score` parameters optional in the content reporting API (MSC2414).
diff --git a/changelogs/server_server/newsfragments/2536.feature b/changelogs/server_server/newsfragments/2536.feature
index 62a66562..c2ea2d32 100644
--- a/changelogs/server_server/newsfragments/2536.feature
+++ b/changelogs/server_server/newsfragments/2536.feature
@@ -1,9 +1,9 @@
Add cross-signing:
-- Add properties to the response of ``GET /user/keys`` and ``GET
- /user/devices/{userId}``.
-- The ``m.device_list_update`` EDU is sent when a device gets a new signature.
-- A new ``m.signing_key_update`` EDU is sent when a user's cross-signing keys
+- Add properties to the response of `GET /user/keys` and `GET
+ /user/devices/{userId}`.
+- The `m.device_list_update` EDU is sent when a device gets a new signature.
+- A new `m.signing_key_update` EDU is sent when a user's cross-signing keys
are changed.
per [MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756).
diff --git a/changelogs/server_server/newsfragments/2688.clarification b/changelogs/server_server/newsfragments/2688.clarification
index 87e7792c..dfecfb59 100644
--- a/changelogs/server_server/newsfragments/2688.clarification
+++ b/changelogs/server_server/newsfragments/2688.clarification
@@ -1 +1 @@
-Specify that ``GET /_matrix/federation/v1/make_join/{roomId}/{userId}`` can return a 404 if the room is unknown.
\ No newline at end of file
+Specify that `GET /_matrix/federation/v1/make_join/{roomId}/{userId}` can return a 404 if the room is unknown.
diff --git a/config.toml b/config.toml
index 625e6fdc..963d2fcd 100644
--- a/config.toml
+++ b/config.toml
@@ -39,7 +39,7 @@ privacy_policy = "https://matrix.org/legal/privacy-notice"
# must be one of "unstable", "current", "historical"
# this is used to decide whether to show a banner pointing to the current release
status = "unstable"
-current_version_url = "https://spec.matrix.org/latest"
+current_version_url = "https://matrix.org/docs/spec/"
# User interface configuration
[params.ui]
diff --git a/content/changelog.md b/content/changelog.md
new file mode 100644
index 00000000..41b0987e
--- /dev/null
+++ b/content/changelog.md
@@ -0,0 +1,47 @@
+---
+title: Changelog
+type: docs
+weight: 1000
+---
+
+{{% changelog/changelog-description %}}
+
+{{% changelog/changelog-changes %}}
+
+Historical versions
+
+Before version 1.1, versioning was applied at the level of individual API specifications. This section includes links to these versions of the APIs.
+
+* **Client-Server API**
+ - [r0.6.1](https://matrix.org/docs/spec/client_server/r0.6.1.html)
+ - [r0.6.0](https://matrix.org/docs/spec/client_server/r0.6.0.html)
+ - [r0.5.0](https://matrix.org/docs/spec/client_server/r0.5.0.html)
+ - [r0.4.0](https://matrix.org/docs/spec/client_server/r0.4.0.html)
+ - [r0.3.0](https://matrix.org/docs/spec/client_server/r0.3.0.html)
+ - [r0.2.0](https://matrix.org/docs/spec/client_server/r0.2.0.html)
+ - [r0.1.0](https://matrix.org/docs/spec/client_server/r0.1.0.html)
+ - [r0.0.1](https://matrix.org/docs/spec/r0.0.1/client_server.html)
+ - [r0.0.0](https://matrix.org/docs/spec/r0.0.0/client_server.html)
+ - [Legacy](https://matrix.org/docs/spec/legacy/#client-server-api):
+ The last draft before the spec was formally released in version
+ r0.0.0.
+
+* **Server-Server API**
+ - [r0.1.4](https://matrix.org/docs/spec/server_server/r0.1.4.html)
+ - [r0.1.3](https://matrix.org/docs/spec/server_server/r0.1.3.html)
+ - [r0.1.2](https://matrix.org/docs/spec/server_server/r0.1.2.html)
+ - [r0.1.1](https://matrix.org/docs/spec/server_server/r0.1.1.html)
+ - [r0.1.0](https://matrix.org/docs/spec/server_server/r0.1.0.html)
+
+* **Application Service API**
+ - [r0.1.1](https://matrix.org/docs/spec/application_service/r0.1.1.html)
+ - [r0.1.0](https://matrix.org/docs/spec/application_service/r0.1.0.html)
+
+* **Identity Service API**
+ - [r0.3.0](https://matrix.org/docs/spec/identity_service/r0.3.0.html)
+ - [r0.2.1](https://matrix.org/docs/spec/identity_service/r0.2.1.html)
+ - [r0.2.0](https://matrix.org/docs/spec/identity_service/r0.2.0.html)
+ - [r0.1.0](https://matrix.org/docs/spec/identity_service/r0.1.0.html)
+
+* **Push Gateway API**
+ - [r0.1.0](https://matrix.org/docs/spec/push_gateway/r0.1.0.html)
diff --git a/layouts/partials/navbar.html b/layouts/partials/navbar.html
index 748d53c1..8a736440 100644
--- a/layouts/partials/navbar.html
+++ b/layouts/partials/navbar.html
@@ -45,8 +45,7 @@
{{ $status := .Site.Params.version.status }}
{{ if ne $status "unstable"}}
- {{ $version_pieces := slice .Site.Params.version.major_version .Site.Params.version.minor_version .Site.Params.version.patch_version}}
- {{ $ret = delimit $version_pieces "." }}
+ {{ $ret = .Site.Params.version.number }}
{{ $ret = delimit (slice "version" $ret) " " }}
{{ end }}
diff --git a/layouts/shortcodes/changelog/changelog-changes.html b/layouts/shortcodes/changelog/changelog-changes.html
new file mode 100644
index 00000000..a1e27728
--- /dev/null
+++ b/layouts/shortcodes/changelog/changelog-changes.html
@@ -0,0 +1,83 @@
+{{/*
+
+ This template is used to render the set of changes in the changelog page.
+
+ It expects to find a directory "changelogs" containing a subdirectory for
+ each of the 5 APIs in the specification. Inside each of these directories
+ it expects to find newsfragments describing changes to that API.
+
+ If the `version.status` setting in config.toml is anything other than
+ "unstable", then it also expects to find a "release.yaml" file in /changelogs,
+ which contains:
+ - `tag`: Git tag for this release
+ - `date`: date of this release
+ It then renders this info a table, before the list of changes.
+
+*/}}
+
+{{ $path := path.Join "changelogs" }}
+{{ $status := .Site.Params.version.status }}
+
+{{ if ne $status "unstable" }}
+{{ $release_info := readFile (path.Join $path "release.yaml") | transform.Unmarshal }}
+
+{{ end }}
+
+Changes since last release
+{{ partial "render-api-changes" (dict "title" "Client-Server API" "id" "client-server-api" "path" (path.Join $path "client_server")) }}
+{{ partial "render-api-changes" (dict "title" "Server-Server API" "id" "server-server-api" "path" (path.Join $path "server_server")) }}
+{{ partial "render-api-changes" (dict "title" "Application Service API" "id" "application-service-api" "path" (path.Join $path "application_service")) }}
+{{ partial "render-api-changes" (dict "title" "Identity Service API" "id" "identity-service-api" "path" (path.Join $path "identity_service")) }}
+{{ partial "render-api-changes" (dict "title" "Push Gateway API" "id" "push-gateway-api" "path" (path.Join $path "push_gateway")) }}
+
+{{ define "partials/render-api-changes" }}
+{{ .title }}
+ {{ $api_path := .path }}
+ {{ $config_file := path.Join $api_path "pyproject.toml" }}
+ {{ $config := readFile $config_file | transform.Unmarshal }}
+ {{ $news_path := path.Join $api_path "newsfragments" }}
+ {{ partial "render-newsfragments" (dict "config" $config "news_path" $news_path )}}
+{{ end }}
+
+{{ define "partials/render-newsfragments" }}
+{{ $config := .config }}
+{{ $news_path := .news_path }}
+
+{{ $types := dict }}
+{{ range $config.tool.towncrier.type }}
+ {{ $types = merge $types (dict .directory (slice)) }}
+{{ end }}
+
+{{ range (readDir $news_path) }}
+
+ {{ $pieces := split .Name "." }}
+
+ {{ $ticket := index $pieces 0 }}
+ {{ $description := readFile (path.Join $news_path .Name ) }}
+ {{ $change_info := (dict "ticket" $ticket "description" $description )}}
+
+ {{ $type := index $pieces 1 }}
+ {{ $instances := index $types $type }}
+ {{ $instances = $instances | append $change_info }}
+ {{ $types = merge $types (dict $type $instances) }}
+
+{{ end }}
+
+
+{{ range $config.tool.towncrier.type }}
+ {{ $changes_of_type := (index $types .directory) }}
+ {{ if $changes_of_type }}
+- {{.name}}
+
+ {{ range $changes_of_type }}
+- {{ .ticket }}: {{ .description | markdownify }}
+ {{ end }}
+
+
+ {{ end }}
+{{ end }}
+
+{{ end }}
diff --git a/layouts/shortcodes/changelog/changelog-description.html b/layouts/shortcodes/changelog/changelog-description.html
new file mode 100644
index 00000000..738ff675
--- /dev/null
+++ b/layouts/shortcodes/changelog/changelog-description.html
@@ -0,0 +1,15 @@
+{{/*
+
+ This template is used to provide different content for the unstable spec
+ version and for a versioned release.
+
+*/}}
+
+{{ $status := .Site.Params.version.status }}
+
+{{ if eq $status "unstable"}}
+This is the unstable version of the Matrix specification.
+This changelog lists changes made since the last release of the specification.
+{{ else }}
+This is version {{ .Site.Params.version.number }} of the Matrix specification.
+{{ end }}