Fix web-docs.element.dev deployment (#32922)

* Fix docs

* Switch to vitepress for doc generation

* Run doc build in CI

* Switch docs build to layered
This commit is contained in:
Michael Telatynski
2026-03-25 18:10:06 +01:00
committed by GitHub
parent ec47986ef5
commit b90a32bea4
33 changed files with 2635 additions and 2183 deletions
+169
View File
@@ -0,0 +1,169 @@
import { withMermaid } from "vitepress-plugin-mermaid";
function customPathResolver(href: string, currentPath: string) {
const [link, fragment] = href.split("#", 2);
if (currentPath === "index.md") {
if (link.startsWith("./docs/")) {
return `../docs/${href.slice(7)}`;
} else if (link.startsWith("docs/")) {
return `../${href}`;
}
}
switch (link) {
case "../packages/shared-components/README.md":
return `../../docs/readme-shared-components.md#${fragment}`;
case "../apps/web/README.md":
return `../../docs/readme-element-web.md#${fragment}`;
case "../README.md":
return `../../docs/index.md#${fragment}`;
default:
return `https://github.com/element-hq/element-web/blob/develop/${href.split("/").pop()}`;
}
}
// https://vitepress.dev/reference/site-config
export default withMermaid({
title: "Element Web & Desktop docs",
description: "Documentation",
srcExclude: ["changelogs", "SUMMARY.md"],
rewrites: {
":file": "docs/:file",
"README": "index",
},
markdown: {
config: (md) => {
// Custom rule to fix links
const defaultRender =
md.renderer.rules.link_open ||
function (tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options);
};
md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
const token = tokens[idx];
const hrefIndex = token.attrIndex("href");
if (hrefIndex >= 0) {
const href = token.attrs![hrefIndex][1];
if (!href.includes("://") && href.split("#", 2)[0].endsWith(".md")) {
token.attrs![hrefIndex][1] = customPathResolver(href, env.relativePath);
}
}
return defaultRender(tokens, idx, options, env, self);
};
},
},
themeConfig: {
nav: [
{ text: "Home", link: "/" },
{ text: "Website", link: "https://element.io/en" },
],
search: {
provider: "local",
},
sidebar: [
{
text: "README",
items: [
{ text: "Introduction", link: "/index" },
{ text: "Element Web", link: "/readme-element-web" },
{ text: "Element Desktop", link: "/readme-element-desktop" },
{ text: "Shared Components", link: "/readme-shared-components" },
],
},
{
text: "Usage",
items: [
{ text: "Betas", link: "/betas" },
{ text: "Labs", link: "/labs" },
],
},
{
text: "Setup",
items: [
{ text: "Install", link: "/install" },
{ text: "Config", link: "/config" },
{ text: "Custom home page", link: "/custom-home" },
{ text: "Kubernetes", link: "/kubernetes" },
{ text: "Jitsi", link: "/jitsi" },
{ text: "Encryption", link: "/e2ee" },
],
},
{
text: "Build",
items: [
{
text: "Web",
items: [
{ text: "Customisations", link: "/customisations" },
{ text: "Deprecated Modules", link: "/deprecated-modules" },
],
},
{
text: "Desktop",
items: [
{ text: "Native Node modules", link: "/native-node-modules" },
{ text: "Windows requirements", link: "/windows-requirements" },
{ text: "Debugging", link: "/debugging" },
{ text: "Using gdb", link: "/gdb" },
],
},
],
},
{
text: "Distribution",
items: [
{ text: "Updates", link: "/updates" },
{ text: "Packaging", link: "/packaging" },
],
},
{
text: "Contribution",
items: [
{ text: "Choosing an issue", link: "/choosing-an-issue" },
{ text: "Translation", link: "/translating" },
{ text: "Netlify builds", link: "/pr-previews" },
{ text: "Code review", link: "/review" },
],
},
{
text: "Development",
items: [
{ text: "App load order", link: "/app-load.md" },
{ text: "Translation", link: "/translating-dev.md" },
{ text: "Theming", link: "/theming.md" },
{ text: "Playwright end to end tests", link: "/playwright.md" },
{ text: "Memory profiling", link: "/memory-profiles-and-leaks.md" },
{ text: "Jitsi", link: "/jitsi-dev.md" },
{ text: "Feature flags", link: "/feature-flags.md" },
{ text: "OIDC and delegated authentication", link: "/oidc.md" },
{ text: "Release Process", link: "/release.md" },
{ text: "MVVM", link: "/MVVM.md" },
{ text: "Settings", link: "/settings.md" },
],
},
{
text: "Deep dive",
items: [
{ text: "Skinning", link: "/skinning" },
{ text: "Cider editor", link: "/ciderEditor" },
{ text: "Iconography", link: "/icons" },
{ text: "Local echo", link: "/local-echo-dev" },
{ text: "Media", link: "/media-handling" },
{ text: "Room List Store", link: "/room-list-store" },
{ text: "Scrolling", link: "/scrolling" },
{ text: "Usercontent", link: "/usercontent" },
{ text: "Widget layouts", link: "/widget-layouts" },
{ text: "Automations", link: "/generated/automations" },
],
},
],
socialLinks: [{ icon: "github", link: "https://github.com/element-hq/element-web" }],
},
});
+1 -1
View File
@@ -1,4 +1,4 @@
# MVVM
# MVVM v1
_Deprecated_, see [MVVM.md](./MVVM.md) for the current version.
+1 -1
View File
@@ -1,4 +1,4 @@
# MVVM
# MVVM v2
General description of the pattern can be found [here](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel). But the gist of it is that you divide your code into three sections:
-56
View File
@@ -1,56 +0,0 @@
# Summary
- [Introduction](../README.md)
# Usage
- [Betas](betas.md)
- [Labs](labs.md)
# Setup
- [Install](install.md)
- [Config](config.md)
- [Custom home page](custom-home.md)
- [Kubernetes](kubernetes.md)
- [Jitsi](jitsi.md)
- [Encryption](e2ee.md)
# Build
- [Customisations](customisations.md)
- [Deprecated Modules](deprecated-modules.md)
- [Native Node modules](native-node-modules.md)
# Contribution
- [Choosing an issue](choosing-an-issue.md)
- [Translation](translating.md)
- [Netlify builds](pr-previews.md)
- [Code review](review.md)
# Development
- [App load order](app-load.md)
- [Translation](translating-dev.md)
- [Theming](theming.md)
- [Playwright end to end tests](playwright.md)
- [Memory profiling](memory-profiles-and-leaks.md)
- [Jitsi](jitsi-dev.md)
- [Feature flags](feature-flags.md)
- [OIDC and delegated authentication](oidc.md)
- [Release Process](release.md)
- [MVVM](MVVM.md)
- [Settings](settings.md)
# Deep dive
- [Skinning](skinning.md)
- [Cider editor](ciderEditor.md)
- [Iconography](icons.md)
- [Local echo](local-echo-dev.md)
- [Media](media-handling.md)
- [Room List Store](room-list-store.md)
- [Scrolling](scrolling.md)
- [Usercontent](usercontent.md)
- [Widget layouts](widget-layouts.md)
+1 -1
View File
@@ -3,7 +3,7 @@
So you want to contribute to Element Web? That is awesome!
If you're not sure where to start, make sure you read
[CONTRIBUTING.md](../CONTRIBUTING.md), and the
[CONTRIBUTING.md](https://github.com/element-hq/element-web/blob/develop/CONTRIBUTING.md), and the
[Development](../README.md#development) and
[Setting up a dev environment](../README.md#setting-up-a-dev-environment)
sections of the README.
+12
View File
@@ -605,3 +605,15 @@ The following are undocumented or intended for developer use only.
2. `sync_timeline_limit`
3. `dangerously_allow_unsafe_and_insecure_passwords`
4. `latex_maths_delims`: An optional setting to override the default delimiters used for maths parsing. See https://github.com/matrix-org/matrix-react-sdk/pull/5939 for details. Only used when `feature_latex_maths` is enabled.
## Additional config options for Element Desktop
1. `update_base_url`: Specifies the URL of the update server, see [document](https://github.com/element-hq/element-web/blob/develop/apps/desktop/docs/updates.md).
2. `web_base_url`: Specifies the Element Web URL when performing actions such as popout widget. Defaults to `https://app.element.io/`.
---
The app contains a configuration file specified at build time using [these instructions](https://github.com/element-hq/element-web/blob/develop/apps/desktop/README.md#config).
This config can be overwritten by the end using by creating a `config.json` file at the paths described [here](https://github.com/element-hq/element-web/blob/develop/apps/desktop/README.md#user-specified-configjson).
After changing the config, the app will need to be exited fully (including via the task tray) and re-started.
+28
View File
@@ -0,0 +1,28 @@
# Debugging Element-Desktop
There are two parts of the desktop app that you might want to debug.
## The renderer process
This is the regular element-web codeand can be debugged by just selecting 'toggle developer tools'
from the menu, even on ppackaged builds. This then works the same as chrome dev tools for element web.
## The main process
This is debugged as a node app, so:
1. Open any chrome dev tools window
1. Start element with the `--inspect-brk` flag
1. Notice that you now have a little green icon in the top left of your chrome devtools window, click it.
You are now debugging the code of the desktop app itself.
## The main process of a package app
When the app is shipped, electron's "fuses" are flipped, editing the electron binary itself to prevent certain features from being usable, one of which is debugging using `--inspect-brk` as above. You can flip the fuse back on Linux as follows:
```
sudo npx @electron/fuses write --app /opt/Element/element-desktop EnableNodeCliInspectArguments=on
```
A similar command will work, in theory, on mac and windows, except that this will break code signing (which is the point of fuses) so you would have to re-sign the app or somesuch.
+45
View File
@@ -0,0 +1,45 @@
# Using gdb against Element-Desktop
Occasionally it is useful to be able to connect to a running Element-Desktop
with [`gdb`](https://sourceware.org/gdb/), or to analayze a coredump. For this,
you will need debug symbols.
1. If you don't already have the right version of Element-Desktop (eg because
you are analyzing someone else's coredump), download and unpack the tarball
from https://packages.element.io/desktop/install/linux/. If it was a
nightly, your best bet may be to download the deb from
https://packages.element.io/debian/pool/main/e/element-nightly/ and unpack
it.
2. Figure out which version of Electron your Element-Desktop is based on. The
best way to do this is to figure out the version of Element-Desktop, then
look at
[`package.json`](https://github.com/element-hq/element-web/blob/develop/apps/desktop/package.json)
for the corresponding version. There will be an entry within `dependencies` of
`electron`: the value will tell you the version of Electron that was used for that version of Element-Desktop.
3. Go to [Electron's releases page](https://github.com/electron/electron/releases/)
and find the version you just identified. Under "Assets", download
`electron-v<version>-linux-x64-debug.zip` (or, the -debug zip corresponding to your
architecture).
4. The debug zip has a structure like:
```
.
├── debug
│   ├── chrome_crashpad_handler.debug
│   ├── electron.debug
│   ├── libEGL.so.debug
│   ├── libffmpeg.so.debug
│   ├── libGLESv2.so.debug
│   └── libvk_swiftshader.so.debug
├── LICENSE
├── LICENSES.chromium.html
└── version
```
Take all the contents of `debug`, and copy them into the Element-Desktop directory,
so that `electron.debug` is alongside the `element-desktop-nightly` executable.
5. You now have a thing you can gdb as normal, either as `gdb --args element-desktop-nightly`, or
`gdb element-desktop-nightly core`.
+1
View File
@@ -0,0 +1 @@
<!-- @content -->
+18
View File
@@ -0,0 +1,18 @@
import genWorkflowMermaid from "../../scripts/gen-workflow-mermaid";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
export default {
async paths() {
const root = join(__dirname, "..", "..");
return [
{
params: { id: "automations" },
content: await genWorkflowMermaid([root, join(root, "node_modules", "matrix-js-sdk")]),
},
];
},
};
+1 -1
View File
@@ -24,7 +24,7 @@ const MyComponent = () => {
}
```
If possible, use the icon classes from [here](../res/css/compound/_Icon.pcss).
If possible, use the icon classes from [here](https://github.com/element-hq/element-web/blob/develop/apps/web/res/css/compound/_Icon.pcss).
## Custom styling
+1
View File
@@ -0,0 +1 @@
<!--@include: ../README.md-->
+2 -2
View File
@@ -1,6 +1,6 @@
# Installing Element Web
**Familiarise yourself with the [Important Security Notes](../README.md#important-security-notes) before starting, they apply to all installation methods.**
**Familiarise yourself with the [Important Security Notes](../apps/web/README.md#important-security-notes) before starting, they apply to all installation methods.**
_Note: that for the security of your chats will need to serve Element over HTTPS.
Major browsers also do not allow you to use VoIP/video chats over HTTP, as WebRTC is only usable over HTTPS.
@@ -11,7 +11,7 @@ There are some exceptions like when using localhost, which is considered a [secu
1. Download the latest version from <https://github.com/element-hq/element-web/releases>
1. Untar the tarball on your web server
1. Move (or symlink) the `element-x.x.x` directory to an appropriate name
1. Configure the correct caching headers in your webserver (see [README.md](../README.md#caching-requirements))
1. Configure the correct caching headers in your webserver (see [README.md](../apps/web/README.md#caching-requirements))
1. Configure the app by copying `config.sample.json` to `config.json` and
modifying it. See the [configuration docs](config.md) for details.
1. Enter the URL into your browser and log into Element!
-14
View File
@@ -1,14 +0,0 @@
/* Prevent collapsible headings from wrapping onto two lines eagerly */
summary > h1,
summary > h2,
summary > h3,
summary > h4,
summary > h5,
summary > h6 {
display: inline-block;
}
/* Prevent longer checkbox lists from wrapping eagerly */
input + p {
display: inline;
}
-1
View File
@@ -1 +0,0 @@
mermaid.initialize({ startOnLoad:true });
-1648
View File
File diff suppressed because one or more lines are too long
+180
View File
@@ -0,0 +1,180 @@
# Native Node Modules
For some features, the desktop version of Element can make use of native Node
modules. These allow Element to integrate with the desktop in ways that a browser
cannot.
While native modules enable powerful new features, they must be complied for
each operating system. For official Element releases, we will always build these
modules from source to ensure we can trust the compiled output. In the future,
we may offer a pre-compiled path for those who want to use these features in a
custom build of Element without installing the various build tools required.
The process is automated by [vector-im/element-builder](https://github.com/vector-im/element-builder)
when releasing.
## Use docker
If you are building for Linux, you can build the native modules with:
```
pnpm docker:setup
pnpm docker:install
INDOCKER_SQLCIPHER_BUNDLED=1 pnpm docker:build:native
```
The above will build `matrix-seshat` in
`docker/node_modules/matrix-seshat`. You can then either run `pnpm docker:build`
to build the app inside docker, or:
```
pnpm link docker/node_modules/matrix-seshat
```
... and build the app with `pnpm build` or run it with `pnpm start`.
(See also https://github.com/element-hq/element-web/blob/develop/apps/desktop/README.md#docker.)
## Building
Install the pre-requisites for your system:
- [Windows pre-requisites](https://github.com/element-hq/element-web/blob/develop/apps/desktop/docs/windows-requirements.md)
- Linux: TODO. Using the docker environment as above is recommended.
- OS X: TODO
Then optionally, [add seshat and dependencies to support search in E2E rooms](#adding-seshat-for-search-in-e2e-encrypted-rooms).
Then, to build for an architecture selected automatically based on your system (recommended), run:
```
pnpm run build:native
```
If you need to build for a specific architecture, see [here](#compiling-for-specific-architectures).
## Adding Seshat for search in E2E encrypted rooms
Seshat is a native Node module that adds support for local event indexing and
full text search in E2E encrypted rooms.
Since Seshat is written in Rust, the Rust compiler and related tools need to be
installed before installing Seshat itself. To install Rust please consult the
official Rust [documentation](https://www.rust-lang.org/tools/install).
Seshat also depends on the SQLCipher library to store its data in encrypted form
on disk. You'll need to install it via your OS package manager.
After installing the Rust compiler and SQLCipher, Seshat support can be added
using pnpm at the root of this project:
pnpm add matrix-seshat
You will have to rebuild the native libraries against electron's version
of node rather than your system node, using the `electron-build-env` tool.
This is also needed to when pulling in changes to Seshat using `pnpm link`.
pnpm add electron-build-env
Recompiling Seshat itself can be done like so:
ELECTRON_VERSION=$(electron --version)
pnpm electron-build-env -- --electron ${ELECTRON_VERSION#v} -- neon build matrix-seshat --release
Please make sure to include all the `--` as well as the `--release` command line
switch at the end. Modify your electron version accordingly depending on the
version that is installed on your system.
After this is done the Electron version of Element can be run from the main folder
as usual using:
pnpm start
### Statically linking libsqlcipher
On Windows & macOS we always statically link libsqlcipher for it is not generally available.
On Linux by default we will use a system package, on debian & ubuntu this is `libsqlcipher0`,
but this is problematic for some other packages, and we found that it may crashes for unknown reasons.
By including `SQLCIPHER_BUNDLED=1` in the build environment, the build scripts will fully statically
link sqlcipher, including a static build of OpenSSL.
More info can be found at https://github.com/matrix-org/seshat/issues/102
and https://github.com/vector-im/element-web/issues/20926.
## Compiling for specific architectures
### macOS
On macOS, you can build universal native modules too:
```
pnpm run build:native:universal
```
...or you can build for a specific architecture:
```
pnpm run build:native --target x86_64-apple-darwin
```
or
```
pnpm run build:native --target aarch64-apple-darwin
```
You'll then need to create a built bundle with the same architecture.
To bundle a universal build for macOS, run:
```
pnpm run build:universal
```
### Windows
If you're on Windows, you can choose to build specifically for 32 or 64 bit:
```
pnpm run build:32
```
or
```
pnpm run build:64
```
### Cross compiling
Compiling a module for a particular operating system (Linux/macOS/Windows) needs
to be done on that operating system. Cross-compiling from a host OS for a different
target OS may be possible, but we don't support this flow with Element dependencies
at this time.
### Switching between architectures
The native module build system keeps the different architectures
separate, so you can keep native modules for several architectures at the same
time and switch which are active using a `pnpm run hak copy` command, passing
the appropriate architectures. This will error if you haven't yet built those
architectures. eg:
```
pnpm run build:native --target x86_64-apple-darwin
# We've now built & linked into place native modules for Intel
pnpm run build:native --target aarch64-apple-darwin
# We've now built Apple Silicon modules too, and linked them into place as the active ones
pnpm run hak copy --target x86_64-apple-darwin
# We've now switched back to our Intel modules
pnpm run hak copy --target x86_64-apple-darwin --target aarch64-apple-darwin
# Now our native modules are universal x86_64+aarch64 binaries
```
The current set of native modules are stored in `.hak/hakModules`,
so you can use this to check what architecture is currently in place, eg:
```
$ lipo -info .hak/hakModules/keytar/build/Release/keytar.node
Architectures in the fat file: .hak/hakModules/keytar/build/Release/keytar.node are: x86_64 arm64
```
+46
View File
@@ -0,0 +1,46 @@
## Packaging nightlies
Element Desktop nightly builds are build automatically by the [Github Actions workflow](https://github.com/vector-im/element-web/blob/develop/.github/workflows/build_desktop_and_deploy.yaml).
The schedule is currently set for once a day at 9am UTC. It will deploy to packages.element.io upon completion.
## Triggering a manual nightly build
Simply go to https://github.com/vector-im/element-web/actions/workflows/build_desktop_and_deploy.yaml
1. Click `Run workflow`
1. Feel free to make changes to the checkboxes depending on the circumstances
1. Click the green `Run workflow`
## Packaging releases
The packaging is kicked off automagically for you when a Github Release for Element Web is published.
### More detail on the github actions
We moved to Github Actions for the following reasons:
1. Removing single point of failure
2. Improving reliability
3. Unblocking the packaging on a single individual
4. Improving parallelism
The Windows builds are signed by SSL.com using their Cloud Key Adapter for eSigner.
This allows us to use Microsoft's signtool to interface with eSigner and send them a hash of the exe along with
credentials in exchange for a signed certificate which we attach onto all the relevant files.
The Apple builds are signed using standard code signing means and then notarised to appease GateKeeper.
The Linux builds are distributed via a signed reprepro repository.
The packages.element.io site is a public Cloudflare R2 bucket which is deployed to solely from Github Actions.
The main bucket in R2 is `packages-element-io` which is a direct mapping of packages.element.io,
we have a workflow which generates the index.html files there to imitate a public index which Cloudflare does not currently support.
The reprepro database lives in `packages-element-io-db`.
There is an additional pair of buckets of same name but appended with `-test` which can be used for testing,
these land on https://packages-element-io-test.element.io/.
### Debian/Ubuntu Distributions
We used to add a new distribution to match each Debian and Ubuntu release. As of April 2020, we have created a `default` distribution that everyone can use (since the packages have never differed by distribution anyway).
The distribution configuration lives in https://github.com/vector-im/packages.element.io/blob/master/debian/conf/distributions as a canonical source.
-22
View File
@@ -1,27 +1,5 @@
# Playwright in Element Web
## Contents
- [Overview](#overview)
- [Prerequisites](#prerequisites)
- [Running the Tests](#running-the-tests)
- [Element Web E2E Tests](#element-web-e2e-tests)
- [Shared Components Tests](#shared-components-tests)
- [Projects](#projects)
- [How the Tests Work](#how-the-tests-work)
- [Test Structure](#test-structure)
- [Homeserver Setup](#homeserver-setup)
- [Fixtures](#fixtures)
- [Writing Tests](#writing-tests)
- [Getting a Homeserver](#getting-a-homeserver)
- [Logging In](#logging-in)
- [Joining a Room](#joining-a-room)
- [Using matrix-js-sdk](#using-matrix-js-sdk)
- [Best Practices](#best-practices)
- [Visual Testing](#visual-testing)
- [Test Tags](#test-tags)
- [Supported Container Runtimes](#supported-container-runtimes)
## Overview
Element Web contains two sets of Playwright tests:
+1
View File
@@ -0,0 +1 @@
<!--@include: ../apps/desktop/README.md-->
+1
View File
@@ -0,0 +1 @@
<!--@include: ../apps/web/README.md-->
+1
View File
@@ -0,0 +1 @@
<!--@include: ../packages/shared-components/README.md-->
+15
View File
@@ -0,0 +1,15 @@
The Desktop app is capable of self-updating on macOS and Windows.
The update server base url is configurable as `update_base_url` in config.json and can be served by a static file host,
CDN or object storage.
Currently all packaging & deployment is handled by [Github actions](https://github.com/vector-im/element-web/blob/develop/.github/workflows/build_desktop_and_deploy.yaml)
# Windows
On Windows the update mechanism used is [Squirrel.Windows](https://github.com/Squirrel/Squirrel.Windows)
and can be served by any compatible Squirrel server, such as https://github.com/Tiliq/squirrel-server
# macOS
On macOS the update mechanism used is [Squirrel.Mac](https://github.com/Squirrel/Squirrel.Mac)
using the newer JSON format as documented [here](https://github.com/Squirrel/Squirrel.Mac#update-file-json-format).
+45
View File
@@ -0,0 +1,45 @@
# Windows
## Requirements to build native modules
We rely on Github Actions `windows-2022` plus a few extra utilities as per [the workflow](https://github.com/vector-im/element-web/blob/develop/.github/workflows/build_desktop_windows.yaml).
If you want to build native modules, make sure that the following tools are installed on your system.
- [Git for Windows](https://git-scm.com/download/win)
- [Node 16](https://nodejs.org)
- [Python 3](https://www.python.org/downloads/) (if you type 'python' into command prompt it will offer to install it from the windows store)
- [Strawberry Perl](https://strawberryperl.com/)
- [Rustup](https://rustup.rs/)
- [NASM](https://www.nasm.us/)
You can install the above tools using [Chocolatey](https://chocolatey.org/install):
```cmd
choco install --no-progress -y git nodejs-lts pnpm python StrawberryPerl rustup.install nasm magicsplat-tcl-tk
```
- [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019) with the following configuration:
- On the Workloads tab:
- Desktop & Mobile -> C++ build tools
- On the Individual components tab:
- MSVC VS 2019 C++ build tools
- Windows 10 SDK (latest version available)
- C++ CMake tools for Windows
Once installed make sure all those utilities are accessible in your `PATH`.
If you want to be able to build x86 targets from an x64 host install the right toolchain:
```cmd
rustup toolchain install stable-i686-pc-windows-msvc
rustup target add i686-pc-windows-msvc
```
In order to load all the C++ utilities installed by Visual Studio you can run the following in a terminal window.
```
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64
```
You can replace `amd64` with `x86` depending on your CPU architecture.