element-web Documentation

A glossy Matrix collaboration client for the web.

13,576 stars TypeScript TypeScript 47 files · ~239,063 tokens #hacktoberfest#matrix
RAW Doc

Technical Documentation: element-hq/element-web

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

Overview (README.md)





Element

Element (formerly known as Vector and Riot) is a Matrix web & desktop client built using the Matrix
JS SDK
.

Supported Environments

Element has several tiers of support for different environments:

  • Supported
    • Definition:
      • Issues actively triaged, regressions block the release
    • Last 2 major versions of Chrome, Firefox, and Edge on desktop OSes
    • Last 2 versions of Safari
    • Latest release of official Element Desktop app on desktop OSes
    • Desktop OSes means macOS, Windows, and Linux versions for desktop devices
      that are actively supported by the OS vendor and receive security updates
  • Best effort
    • Definition:
      • Issues accepted, regressions do not block the release
      • The wider Element Products (including Element Call and the Enterprise Server Suite) do still not officially support these browsers.
      • The element web project and its contributors should keep the client functioning and gracefully degrade where other sibling features (E.g. Element Call) may not function.
    • Last major release of Firefox ESR and Chrome/Edge Extended Stable
  • Community Supported
    • Definition:
      • Issues accepted, regressions do not block the release
      • Community contributions are welcome to support these issues
    • Mobile web for current stable version of Chrome, Firefox, and Safari on Android, iOS, and iPadOS
  • Not supported
    • Definition: Issues only affecting unsupported environments are closed
    • Everything else

The period of support for these tiers should last until the releases specified above, plus 1 app release cycle(2 weeks). In the case of Firefox ESR this is extended further to allow it land in Debian Stable.

For accessing Element on an Android or iOS device, we currently recommend the
native apps element-x-android
and element-x-ios.

Getting Started

The easiest way to test Element is to just use the hosted copy at https://app.element.io.
The develop branch is continuously deployed to https://develop.element.io
for those who like living dangerously.

To host your own instance of Element see Installing Element Web.

To install Element as a desktop application, see Running as a desktop app below.


Monorepo

This repository is a monorepo hosting Element Web and other related projects in various subdirectories.
You can read more about the structure here.

Element Web

To learn more about Element Web click here

Running as a Desktop app

Element can also be run as a desktop app, wrapped in Electron. You can download a
pre-built version from https://element.io/get-started or, if you prefer,
build it yourself.

To build it yourself, follow the instructions at https://github.com/element-hq/element-web/tree/develop/apps/desktop.

Many thanks to @aviraldg for the initial work on the Electron integration.

The configuration docs show how to override the desktop app's default settings if desired.

Development

Please read through the following:

  1. Developer guide
  2. Code style
  3. Contribution guide

Translations

To add a new translation, head to the translating doc.

For a developer guide, see the translating dev doc.

Triaging issues

Issues are triaged by community members and the Web App Team, following the triage process.

We use issue labels to sort all incoming issues.

Copyright (c) 2014-2017 OpenMarket Ltd
Copyright (c) 2017 Vector Creations Ltd
Copyright (c) 2017-2025 New Vector Ltd

This software is multi licensed by New Vector Ltd (Element). It can be used either:

(1) for free under the terms of the GNU Affero General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR

(2) for free under the terms of the GNU General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR

(3) under the terms of a paid-for Element Commercial License agreement between you and Element (the terms of which may vary depending on what you and Element have agreed to).
Unless required by applicable law or agreed to in writing, software distributed under the Licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licenses for the specific language governing permissions and limitations under the Licenses.

Please contact [email protected] to purchase
an Element commercial license for this software.


Features README (`docs/features/README.md`)

Feature documention

The idea of this folder is to document the features we support in different parts of the app.
In case anyone needs to work on a given part, and isn't aware of all the features in the area,
they will hopefully get an idea for all the supported functionality to know what to take into account
when making changes.


MVVM V1 (`docs/MVVM-v1.md`)

MVVM v1

Deprecated, see MVVM.md for the current version.

General description of the pattern can be found here. But the gist of it is that you divide your code into three sections:

  1. Model: This is where the business logic and data resides.
  2. View Model: This code exists to provide the logic necessary for the UI. It directly uses the Model code.
  3. View: This is the UI code itself and depends on the view model.

If you do MVVM right, your view should be dumb i.e it gets data from the view model and merely displays it.

Practical guidelines for MVVM in element-web

Model

This is anywhere your data or business logic comes from. If your view model is accessing something simple exposed from matrix-js-sdk, then the sdk is your model. If you're using something more high level in element-web to get your data/logic (eg: MemberListStore), then that becomes your model.

View Model

  1. View model is always a custom react hook named like useFooViewModel().
  2. The return type of your view model (known as view state) must be defined as a typescript interface:
    ts
    inteface FooViewState {
        somethingUseful: string;
        somethingElse: BarType;
        update: () => Promise<void>
        ...
    }
  3. Any react state that your UI needs must be in the view model.

View

  1. Views are simple react components (eg: FooView).
  2. Views usually start by calling the view model hook, eg:
    tsx
    const FooView: React.FC<IProps> = (props: IProps) => {
        const vm = useFooViewModel();
        ....
        return(
            <div>
                {vm.somethingUseful}
            </div>
        );
    }
  3. Views are also allowed to accept the view model as a prop, eg:
    tsx
    const FooView: React.FC<IProps> = ({ vm }: IProps) => {
        ....
        return(
            <div>
                {vm.somethingUseful}
            </div>
        );
    }
  4. Multiple views can share the same view model if necessary.

Benefits

  1. MVVM forces a separation of concern i.e we will no longer have large react components that have a lot of state and rendering code mixed together. This improves code readability and makes it easier to introduce changes.
  2. Introduces the possibility of code reuse. You can reuse an old view model with a new view or vice versa.
  3. Adding to the point above, in future you could import element-web view models to your project and supply your own views thus creating something similar to the hydrogen sdk.

Example

We started experimenting with MVVM in the redesigned memberlist, you can see the code here.


MVVM (`docs/MVVM.md`)

MVVM v2

General description of the pattern can be found here. But the gist of it is that you divide your code into three sections:

  1. Model: This is where the business logic and data resides.
  2. View Model: This code exists to provide the logic necessary for the UI. It directly uses the Model code.
  3. View: This is the UI code itself and depends on the view model.

If you do MVVM right, your view should be dumb i.e it gets data from the view model and merely displays it.

Why are we using MVVM?

  1. MVVM forces a separation of concern i.e we will no longer have large react components that have a lot of state and rendering code mixed together. This improves code readability and makes it easier to introduce changes.
  2. Introduces the possibility of code reuse. You can reuse an old view model with a new view or vice versa.
  3. Adding to the point above, in future you could import element-web view models to your project and supply your own views thus creating something similar to the hydrogen sdk.

Practical guidelines for MVVM in element-web

A first documentation and implementation of MVVM was done in MVVM-v1.md. This v1 version is now deprecated and this document describes the current implementation.

Naming conventions

Given a feature named Foo, the naming convention for each MVVM artifact is:

Artifact Name
View component FooView
Snapshot interface FooViewSnapshot
Actions interface FooViewActions
ViewModel type alias (in view file) FooViewModel
ViewModel class (in apps/web) FooViewModel
ViewModel class file FooViewModel.ts

Model

This is anywhere your data or business logic comes from. If your view model is accessing something simple exposed from matrix-js-sdk, then the sdk is your model. If you're using something more high level in element-web to get your data/logic (eg: MemberListStore), then that becomes your model.

View

  1. Located in shared-components. Develop it in storybook!
  2. Views are simple react components (eg: FooView) with very little state and logic.
  3. Views must call useViewModel hook with the corresponding view model passed in as argument. This allows the view to re-render when something has changed in the view model. This entire mechanism is powered by useSyncExternalStore.
  4. Views should define the interface of the view model (see example below).
  5. Multiple views can share the same view model if necessary.

Example of view implementation

tsx
// Snapshot is the data that your view-model provides which is rendered by the view.
export interface FooViewSnapshot {
    title: string;
    description: string;
}

// To call function on the view model
interface FooViewActions {
    setTitle: (title: string) => void;
    reloadDescription: () => void;
}

// ViewModel is an object (usually a class) that implements both the interfaces listed above.
// https://github.com/element-hq/element-web/blob/develop/packages/shared-components/src/ViewModel.ts
export type FooViewModel = ViewModel<FooViewSnapshot, FooViewActions>;

interface FooViewProps {
    // Ideally the view only depends on the view model i.e you don't expect any other props here.
    vm: FooViewModel;
}

export function FooView({ vm }: FooViewProps): JSX.Element {
    // useViewModel is a hook that subscribes to the view model and returns the snapshot. It also ensures that the component re-renders when the snapshot changes.
    const { title, description } = useViewModel(vm);
    return (
        <section>
            <h1>{title}</h1>
            {/* Bind setTitle action */}
            <button type="button" onClick={() => vm.setTitle("new title!")}>
                Set title
            </button>
            <p>{description}</p>
            {/* Bind reloadDescription action  */}
            <button type="button" onClick={() => vm.reloadDescription()}>
                Reload description
            </button>
        </section>
    );
}

View Model

  1. A View model is a class extending BaseViewModel.
  2. Implements the interface defined in the view (e.g FooViewModel in the example above).
  3. View models define a snapshot type that defines the data the view will consume. The snapshot is immutable and can only be changed by calling this.snapshot.set(...) or this.snapshot.merge(...) in the view model. This will trigger a re-render in the view.
  4. Call this.snapshot.merge(...) to only update part of the snapshot. merge(...) already skips emitting when the merged fields are unchanged, so avoid extra equality guards that only duplicate that check.
  5. Avoid recomputing the entire snapshot when you only need to update a single field. For performance reasons, only recompute the fields that have actually changed. For example, if only title has changed, call this.snapshot.merge({ title: newTitle }) rather than rebuilding the full snapshot object with all fields recomputed.
  6. View models can have props which are passed in the constructor. Props are usually used to pass in dependencies (eg: stores, sdk, etc) that the view model needs to do its work. They can also be used to pass in initial values for the snapshot.

Example of a view model implementation

text
/* Detailed source-code truncated for AI context efficiency. */

Binding of View Model Actions:

All view model actions must be defined as arrow functions to ensure they are bound to the class instance.

Using standard class methods can result in this being undefined when the function is passed as a callback (e.g. to a React event handler), which may cause runtime errors.

Correct pattern:

ts
public doSomething = (): void => {
    ...
};

`useViewModel` hook

Your view must call this hook with the view-model as argument. Think of this as your view subscribing to the view model.
This hook returns the snapshot from your view-model.

Disposables and helper hooks

Disposables provide a mechanism for tracking and releases resources. This is necessary for avoiding memory leaks.

Lifecycle of a view model

The lifecycle of a given view model is from its creation (usually through the constructor i.e new FooViewModel(prop1, prop2)) to the time the dispose method on it is called (eg: fooViewModel.dispose()). It is the responsibility of whoever creates the view model to call the dispose method when the view model is no longer necessary.

Disposable work by tracking anything that needs to be disposed of and then sequentially disposing them when viewModel.dispose() is called.

How to use disposables

Consider the following scenarios:

Scenario 1: Your view model listens to some event on an event emitter

In the example given below, how do you ensure that the listener on props.emitter is removed when the view model is disposed?

ts
class FooViewModel ... {
    constructor(props: Props) {
        ...
        props.emitter.on("my-event", this.doSomething());
    }
}

You can use disposables to remove the listener when the view-model is disposed:

ts
class FooViewModel ... {
    constructor(props: Props) {
        ...
        this.disposables.trackListener(props.emitter, "my-event", this.doSomething());
    }
}

Scenario 2: Your view model creates sub view models

ts
class FooViewModel ... {
    constructor(props: Props) {
        ...
        this.barViewModel = new BarViewModel(...);
    }
}

Here, we want to ensure that when FooViewModel.dispose() is called, it also disposes any sub view models (in this case BarViewModel):

ts
class FooViewModel ... {
    constructor(props: Props) {
        ...
        this.barViewModel = this.disposables.track(new BarViewModel(...));
    }
}

Scenario 3: Tracking and disposing arbitrary resources

A disposable is:

  • a function
  • an object with dispose method (like a view model)

You can therefore use disposables to track any resource that must be eventually relinquished, eg:

ts
class Call {
    ....
    public endCall();
    public stopConnections();
}

class CallViewModel {
    ...
    constructor(props: Props) {
        const call = new Call();
        // When the view model is disposed, the following call methods will be called
        this.disposables.track(() => {
            call.endCall();
            call.stopConnections();
        });
    }
}

Disposing view models from non-MVVMed react components

While we eventually want all our UI code to use MVVM, the current reality is that most of the existing code is just normal react components. We follow a bottoms up approach when it comes to moving code over to MVVM i.e we deal with child components before dealing with parent components.

This means that you need to dispose child view models from the non-MVVMed parent component.

Class component:

Create the view model in componentDidMount() and dispose the view model in componentWillUnmount():

ts
class FooComponent extends Component {
    componentDidMount() {
        this.barViewModel = new BarViewModel(...);
    }

    componentWillUnmount() {
        this.barViewModel.dispose();
    }
}

Functional Component:

Use the useCreateAutoDisposedViewModel hook:

ts
export function FooComponent(props) {
    const vm = useCreateAutoDisposedViewModel(() => new BarViewModel(...));
    return <BarView vm={vm}>;
}

This hook will call the dispose method on the view model when FooComponent is unmounted.


App Load (`docs/app-load.md`)

App load order

Dev note: As of March 2022, the skin is no longer part of the app load order at all. The document's graphs have
been kept untouched for posterity.

Old slow flow:

mermaid
flowchart TD
    A1(((load_modernizr))) --> B
    A2((rageshake)) --> B
    B(((skin))) --> C
    C(((olm))) --> D
    D{mobile} --> E
    E((config)) --> F
    F((i18n)) --> G
    style F stroke:lime
    G(((theme))) --> H
    H(((modernizr))) --> app
    style H stroke:red

Current more parallel flow:

mermaid
flowchart TD
    subgraph index.ts
        style index.ts stroke:orange

        A[/rageshake/] --> B{mobile}
        B-- No -->C1(.)
        B-- Yes -->C2((redirect))
        C1 --> D[/olm/] --> R
        C1 --> E[platform] --> F[/config/]
        F --> G1[/skin/]
        F --> R
        G1 --> H
        G1 --> R
        F --> G2[/theme/]
        G2 --> H
        G2 --> R
        F --> G3[/i18n/]
        G3 --> H
        G3 --> R
        H{modernizr}-- No --> J((incompatible))-- user ignore --> R
        H-- Yes --> R

        linkStyle 0,7,9,11,12,14,15 stroke:blue;
        linkStyle 4,8,10,13,16 stroke:red;
    end

    R>ready] --> 2A
    style R stroke:gray

    subgraph init.tsx
        style init.tsx stroke:lime
        2A[loadApp] --> 2B[matrixchat]
    end

Key:

  • Parallelogram: async/await task
  • Box: sync task
  • Diamond: conditional branch
  • Circle: user interaction
  • Blue arrow: async task is allowed to settle but allowed to fail
  • Red arrow: async task success is asserted

Notes:

  • A task begins when all its dependencies (arrows going into it) are fulfilled.
  • The success of setting up rageshake is never asserted, element-web has a fallback path for running without IDB (and thus rageshake).
  • Everything is awaited to be settled before the Modernizr check, to allow it to make use of things like i18n if they are successful.

Underlying dependencies:

mermaid
flowchart TD
    A((rageshake))
    B{mobile}
    C((config))
    D(((olm)))
    E((i18n))
    F(((load_modernizr)))
    G(((modernizr)))
    H(((skin)))
    I(((theme)))
    X[app]

    A --> G
    A --> B
    A-- assert -->X
    F --> G --> X
    G --> H --> X
    C --> I --> X
    C --> E --> X
    E --> G
    B --> C-- assert -->X
    B --> D --> X

    style X stroke:red
    style G stroke:red
    style E stroke:lime
    linkStyle 0,11 stroke:yellow;
    linkStyle 2,13 stroke:red;

Betas (`docs/betas.md`)

Beta Features

A feature is marked as beta when it is nearly ready for production and the
team would like to gather wider feedback before turning it on by default.

Betas are visible to all users, including users who have disabled labs settings
tab

Be warned! Beta features are not considered stable and should not be relied upon!

Requirements

A beta feature MUST first become a labs feature before it can become a beta (see
Labs).

A beta feature MUST have an expected timeline to be upgraded to a stable feature. This timeline
should not exceed 3 months. If a feature persists in beta for longer and hasn't been explicitly
extended, the feature MAY be backed out to labs.

A beta feature SHOULD have a rollback path for users to opt-out. If a feature is irreversible or
could corrupt a user's session or account, it should not be in beta. If this is not possible, it
MUST be discussed with the team first to devise an alternative strategy.

A beta feature SHOULD have analytics so that the team can understand how many users
are using it.

Current Betas

This is the current set of betas enabled in Element Web.

Video rooms (`feature_video_rooms`)

Enables support for creating and joining video rooms, which are persistent video
chats that users can jump in and out of.

New notifications settings (`feature_notification_settings2`) [Beta]

Replaces the legacy notification settings with a new one to manage push rules.

Warning This feature has options which are not backwards compatible, disabling
it may have unintended consequences.


Choosing An Issue (`docs/choosing-an-issue.md`)

Choosing an issue to work on

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, and the
Development and
Setting up a dev environment
sections of the README.

Maybe you've got something specific you'd like to work on? If so, make sure you
create an issue and
discuss it with the developers
before you put a lot of time into it.

If you're looking for inspiration on where to start, keep reading!

Finding a good first issue

All the issues for Element Web live in the
element-web repository, including
issues that actually need fixing in one of the related repos.

The first place to look is for
issues tagged with "good first issue".

Look through that list and find something that catches your interest. If there
is nothing, there, try gently asking in
#element-dev:matrix.org for
someone to add something.

When you're looking through the list, here are some things that might make an
issue a GOOD choice:

  • It is a problem or feature you care about.
  • It concerns a type of code you know a little about.
  • You think you can understand what's needed.
  • It already has approval from Element Web's designers (look for comments from
    members of the
    Product or
    Design teams).

Here are some things that might make it a BAD choice:

  • You don't understand it (maybe add a comment asking a clarifying question).
  • It sounds difficult, or is part of a larger change you don't know about.
  • It is tagged with X-Needs-Design or X-Needs-Product.

Element Web's Design and Product teams tend to be very busy, so if you make
changes that require approval from one of those teams, you will probably have
to wait a very long time. The kind of change affected by this is changing the
way the product works, or how it looks in a specific area.

Finding a good second issue

Once you've fixed a few small things, you can consider taking on something a
little larger. This should mostly be driven by what you find interesting, but
you may also find the
Help Wanted
label useful.

Note that the same comment applies as in the previous section: if you want to
work in areas that require Design or Product approval, you should look to join
existing work that is already designed, as getting approval for your random
change will take a very long time.

So you should always avoid issues tagged with X-Needs-Design or
X-Needs-Product
.

Asking questions

Feel free to ask questions about the issues or how to choose them in the
#element-dev:matrix.org Matrix
room.

Thank you

Thank you again for contributing to Element Web. We welcome your contributions
and are grateful for your work. We find working on it great fun, and we hope
you do too!


CiderEditor (`docs/ciderEditor.md`)

The CIDER (Contenteditable-Input-Diff-Error-Reconcile) editor

The CIDER editor is a custom editor written for Element.
Most of the code can be found in the /editor/ directory.
It is used to power the composer main composer (both to send and edit messages), and might be used for other usecases where autocomplete is desired (invite box, ...).

High-level overview.

The editor is backed by a model that contains parts.
A part has some text and a type (plain text, pill, ...). When typing in the editor,
the model validates the input and updates the parts.
The parts are then reconciled with the DOM.

Inner workings

When typing in the contenteditable element, the input event fires and
the DOM of the editor is turned into a string. The way this is done has
some logic to it to deal with adding newlines for block elements, to make sure
the caret offset is calculated in the same way as the content string, and to ignore
caret nodes (more on that later).
For these reasons it doesn't use innerText, textContent or anything similar.
The model addresses any content in the editor within as an offset within this string.
The caret position is thus also converted from a position in the DOM tree
to an offset in the content string. This happens in getCaretOffsetAndText in dom.ts.

Once the content string and caret offset is calculated, it is passed to the update()
method of the model. The model first calculates the same content string of its current parts,
basically just concatenating their text. It then looks for differences between
the current and the new content string. The diffing algorithm is very basic,
and assumes there is only one change around the caret offset,
so this should be very inexpensive. See diff.ts for details.

The result of the diffing is the strings that were added and/or removed from
the current content. These differences are then applied to the parts,
where parts can apply validation logic to these changes.

For example, if you type an @ in some plain text, the plain text part rejects
that character, and this character is then presented to the part creator,
which will turn it into a pill candidate part.
Pill candidate parts are what opens the auto completion, and upon picking a completion,
replace themselves with an actual pill which can't be edited anymore.

The diffing is needed to preserve state in the parts apart from their text
(which is the only thing the model receives from the DOM), e.g. to build
the model incrementally. Any text that didn't change is assumed
to leave the parts it intersects alone.

The benefit of this is that we can use the input event, which is broadly supported,
to find changes in the editor. We don't have to rely on keyboard events,
which relate poorly to text input or changes, and don't need the beforeinput event,
which isn't broadly supported yet.

Once the parts of the model are updated, the DOM of the editor is then reconciled
with the new model state, see renderModel in render.ts for this.
If the model didn't reject the input and didn't make any additional changes,
this won't make any changes to the DOM at all, and should thus be fairly efficient.

For the browser to allow the user to place the caret between two pills,
or between a pill and the start and end of the line, we need some extra DOM nodes.
These DOM nodes are called caret nodes, and contain an invisble character, so
the caret can be placed into them. The model is unaware of caret nodes, and they
are only added to the DOM during the render phase. Likewise, when calculating
the content string, caret nodes need to be ignored, as they would confuse the model.

As part of the reconciliation, the caret position is also adjusted to any changes
the model made to the input. The caret is passed around in two formats.
The model receives the caret offset within the content string (which includes
an atNodeEnd flag to make it unambiguous if it is at a part and or the next part start).
The model converts this to a caret position internally, which has a partIndex
and an offset within the part text, which is more natural to work with.
From there on, the caret position is used, also during reconciliation.


Config (`docs/config.md`)

Configuration

🦖 Deprecation notice

Configuration keys were previously a mix of camelCase and snake_case.
We standardised to snake_case but added compatibility for camelCase to all settings.
This backwards compatibility will be getting removed in a future release so please ensure you are using snake_case.


You can configure the app by copying config.sample.json to config.json or config.$domain.json and customising it.
Element will attempt to load first config.$domain.json and if it fails config.json. This mechanism allows different
configuration options depending on if you're hitting e.g. app1.example.com or app2.example.com. Configs are not mixed
in any way, it either entirely uses the domain config, or entirely uses config.json.

The possible configuration options are described here. If you run into issues, please visit
#element-web:matrix.org on Matrix.

For a good example of a production-tuned config, see https://app.element.io/config.json

For an example of a development/beta-tuned config, see https://develop.element.io/config.json

After changing the config, the app will need to be reloaded. For web browsers this is a simple page refresh, however
for the desktop app the application will need to be exited fully (including via the task tray) and re-started.

Homeserver configuration

In order for Element to even start you will need to tell it what homeserver to connect to by default. Users will be
able to use a different homeserver if they like, though this can be disabled with "disable_custom_urls": true in your
config.

One of the following options must be supplied:

  1. default_server_config: The preferred method of setting the homeserver connection information. Simply copy/paste
    your /.well-known/matrix/client
    into this field. For example:
    json
    {
        "default_server_config": {
            "m.homeserver": {
                "base_url": "https://matrix-client.matrix.org"
            },
            "m.identity_server": {
                "base_url": "https://vector.im"
            }
        }
    }
  2. default_server_name: A different method of connecting to the homeserver by looking up the connection information
    using .well-known. When using this option, simply use your server's domain name (the part at the end of user IDs):
    "default_server_name": "matrix.org"
  3. default_hs_url and (optionally) default_is_url: A very deprecated method of defining the connection
    information. These are the same values seen as base_url in the default_server_config example, with default_is_url
    being optional.

If both default_server_config and default_server_name are used, Element will try to look up the connection
information using .well-known, and if that fails, take default_server_config as the homeserver connection
information.

  1. enable_client_well_known_lookups: Controls whether Element makes runtime requests to the logged-in user's
    <server_name>/.well-known/matrix/...
    endpoints (for example, polling for client configuration after login). Set it to false to stop Element making these
    requests, so it only contacts the homeserver base URL; the well_known object returned inline in the /login response
    is unaffected. Defaults to true.
    This option covers those runtime requests only; login-time .well-known autodiscovery is separate. Setting
    default_server_config with disable_custom_urls: true fixes the homeserver and removes the server picker, covering
    the startup lookup and server selection. It also doesn't cover the legacy password login form (not shown for delegated authentication/OIDC) which performs its own .well-known lookup when a full Matrix ID is entered.

Labs flags

Labs flags are optional, typically beta or in-development, features that can be turned on or off. The full range of
labs flags and their development status are documented here. If interested, the feature flag process is
documented here.

To force a labs flag on or off, use the following:

json
{
    "features": {
        "feature_you_want_to_turn_on": true,
        "feature_you_want_to_keep_off": false
    }
}

If you'd like the user to be able to self-select which labs flags they can turn on, add "show_labs_settings": true to
your config. This will turn on the tab in user settings.

Note: Feature support varies release-by-release. Check the labs flag documentation frequently if enabling
the functionality.

Default settings

Some settings additionally support being specified at the config level to affect the user experience of your Element Web
instance. As of writing those settings are not fully documented, however a few are:

  1. default_federate: When true (default), rooms will be marked as "federatable" during creation. Typically this setting
    shouldn't be used as the federation capabilities of a room cannot be changed after the room is created.
  2. default_country_code: An optional ISO 3166 alpha2 country code (eg: GB, the default) to use when showing phone number
    inputs.
  3. room_directory: Optionally defines how the room directory component behaves. Currently only a single property, servers
    is supported to add additional servers to the dropdown. For example:
    json
    {
        "room_directory": {
            "servers": ["matrix.org", "example.org"]
        }
    }
  4. setting_defaults: Optional configuration for settings which are not described by this document and support the config
    level. This list is incomplete. For example:
    json
    {
        "setting_defaults": {
            "MessageComposerInput.showStickersButton": false,
            "MessageComposerInput.showPollsButton": false
        }
    }
    These values will take priority over the hardcoded defaults for the settings. For a list of available settings, see
    Settings.tsx.

Customisation & branding

Element supports some customisation of the user experience through various branding and theme options. While it doesn't support
complete re-branding/private labeling, a more personalised experience can be achieved for your users.

  1. default_theme: Typically either light (the default) or dark, this is the optional name of the colour theme to use.
    If using custom themes, this can be a theme name from that as well.
  2. default_device_display_name: Optional public name for devices created by login and registration, instead of the default
    templated string. Note that this option does not support templating, currently.
  3. brand: Optional name for the app. Defaults to Element. This is used throughout the application in various strings/locations.
  4. permalink_prefix: An optional URL pointing to an Element Web deployment. For example, https://app.element.io. This will
    change all permalinks (via the "Share" menus) to point at the Element Web deployment rather than matrix.to.
  5. desktop_builds: Optional. Where the desktop builds for the application are, if available. This is explained in more detail
    down below.
  6. mobile_builds: Optional. Like desktop_builds, except for the mobile apps. Also described in more detail down below.
  7. mobile_guide_toast: When true (default), users accessing the Element Web instance from a mobile device will be prompted to
    download the app instead.
  8. mobile_guide_app_variant: Optional. The mobile app that the user is prompted to download from the /mobile_guide page. When omitted
    the mobile guide will be configured for the new Element X apps. Allowed values are as follows:
    1. element: Element X Android/iOS.
    2. element-classic: Element Classic Android/iOS.
    3. element-pro: Element Pro Android/iOS.
  9. update_base_url: For the desktop app only, the URL where to acquire update packages. If specified, must be a path to a directory
    containing macos and win32 directories, with the update packages within. Defaults to https://packages.element.io/desktop/update/
    in production.
  10. map_style_url: Map tile server style URL for location sharing. e.g. https://api.maptiler.com/maps/streets/style.json?key=YOUR_KEY_GOES_HERE
    This setting is ignored if your homeserver provides /.well-known/matrix/client in its well-known location, and the JSON file
    at that location has a key m.tile_server (or the unstable version org.matrix.msc3488.tile_server). In this case, the
    configuration found in the well-known location is used instead.
  11. welcome_user_id: DEPRECATED An optional user ID to start a DM with after creating an account. Defaults to nothing (no DM created).
  12. custom_translations_url: An optional URL to allow overriding of translatable strings. The JSON file must be in a format of
    {"affected|translation|key": {"languageCode": "new string"}}. See https://github.com/matrix-org/matrix-react-sdk/pull/7886 for details.
  13. branding: Options for configuring various assets used within the app. Described in more detail down below.
  14. embedded_pages: Further optional URLs for various assets used within the app. Described in more detail down below.
  15. disable_3pid_login: When false (default), enables the options to log in with email address or phone number. Set to
    true to hide these options.
  16. disable_login_language_selector: When false (default), enables the language selector on the login pages. Set to true
    to hide this dropdown.
  17. disable_guests: When false (default), enable guest-related functionality (peeking/previewing rooms, etc) for unregistered
    users. Set to true to disable this functionality.
  18. user_notice: Optional notice to show to the user, e.g. for sunsetting a deployment and pushing users to move in their own time.
    Takes a configuration object as below:
    1. title: Required. Title to show at the top of the notice.
    2. description: Required. The description to use for the notice.
    3. show_once: Optional. If true then the notice will only be shown once per device.
  19. help_url: The URL to point users to for help with the app, defaults to https://element.io/help.
  20. help_encryption_url: The URL to point users to for help with encryption, defaults to https://element.io/help#encryption.
  21. help_key_storage_url: The URL to point users to for help with key storage, defaults to https://element.io/help#encryption5.
  22. force_verification: If true, users must verify new logins (eg. with another device / their recovery key)

`desktop_builds` and `mobile_builds`

These two options describe the various availability for the application. When the app needs to promote an alternative download,
such as trying to get the user to use an Android app or the desktop app for encrypted search, the config options will be looked
at to see if the link should be to somewhere else.

Starting with desktop_builds, the following sub-properties are available:

  1. available: Required. When true, the desktop app can be downloaded from somewhere.
  2. logo: Required. A URL to a logo (SVG), intended to be shown at 24x24 pixels.
  3. url: Required. The download URL for the app. This is used as a hyperlink.
  4. url_macos: Optional. Direct link to download macOS desktop app.
  5. url_win64: Optional. Direct link to download Windows x86 64-bit desktop app.
  6. url_win64arm: Optional. Direct link to download Windows ARM 64-bit desktop app.
  7. url_linux: Optional. Direct link to download Linux desktop app.

When desktop_builds is not specified at all, the app will assume desktop downloads are available from https://element.io

For mobile_builds, the following subproperties are available:

  1. ios: The URL for where to download the iOS app, such as an App Store link. When explicitly null, the app will assume the
    iOS app cannot be downloaded. When not provided, the default Element app will be assumed available.
  2. android: The same as ios, except for Android instead.
  3. fdroid: The same as android, except for FDroid instead.

Together, these two options might look like the following in your config:

json
{
    "desktop_builds": {
        "available": true,
        "logo": "https://example.org/assets/logo-small.svg",
        "url": "https://example.org/not_element/download"
    },
    "mobile_builds": {
        "ios": null,
        "android": "https://example.org/not_element/android",
        "fdroid": "https://example.org/not_element/fdroid"
    }
}

`branding` and `embedded_pages`

These two options point at various URLs for changing different internal pages (like the welcome page) and logos within the
application.

Starting with branding, the following subproperties are available:

  1. welcome_background_url: When a string, the URL for the full-page image background of the login, registration, and welcome
    pages. This property can additionally be an array to have the app choose an image at random from the selections.
  2. logo_link_url: When rendering the a brand Logo, if it is linkified, this is the link it should direct to. Defaults to https://element.io.
  3. auth_header_logo_url: A URL to the logo used on the login, registration, etc pages.
  4. auth_footer_links: A list of links to add to the footer during login, registration, etc. Each entry must have a text and
    url property.

embedded_pages can be configured as such:

  1. welcome_url: A URL to an HTML page to show as a welcome page (landing on #/welcome).
    When not specified, a default internal component will be used instead.
  2. home_url: A URL to an HTML page to show within the app as the "home" page. When the app doesn't have a room/screen to
    show the user, it will use the home page instead. The home page is additionally accessible from the user menu. By default,
    no home page is set and therefore a hardcoded landing screen is used. More documentation and examples are here.
  3. login_for_welcome: When true (default false), the app will use the login form as a welcome page instead of the welcome
    page itself. This disables use of welcome_url and all welcome page functionality.

Together, the options might look like this in your config:

json
{
    "branding": {
        "welcome_background_url": "https://example.org/assets/background.jpg",
        "auth_header_logo_url": "https://example.org/assets/logo.svg",
        "auth_footer_links": [
            { "text": "FAQ", "url": "https://example.org/faq" },
            { "text": "Donate", "url": "https://example.org/donate" }
        ]
    },
    "embedded_pages": {
        "welcome_url": "https://example.org/assets/welcome.html",
        "home_url": "https://example.org/assets/home.html"
    }
}

Note that index.html also has an og:image meta tag that is set to an image hosted on element.io. This is the image used if
links to your copy of Element appear in some websites like Facebook, and indeed Element itself. This has to be static in the HTML
and an absolute URL (and HTTP rather than HTTPS), so it's not possible for this to be an option in config.json. If you'd like to
change it, you can build Element, but run RIOT_OG_IMAGE_URL="http://example.com/logo.png" pnpm build. Alternatively, you can edit
the og:image meta tag in index.html directly each time you download a new version of Element.

SSO setup

When Element is deployed alongside a homeserver with SSO-only login, some options to ease the user experience might want to be set:

  1. logout_redirect_url: Optional URL to redirect the user to after they have logged out. Some SSO systems support a page that the
    user can be sent to in order to log them out of that system too, making logout symmetric between Element and the SSO system.
  2. sso_redirect_options: Options to define how to handle unauthenticated users. If the object contains "immediate": true, then
    all unauthenticated users will be automatically redirected to the SSO/OIDC system to start their login. If instead you'd only like to
    have users which land on the welcome page to be redirected, use "on_welcome_page": true. Additionally, there is an option to
    redirect anyone landing on the login page, by using "on_login_page": true. As an example:
    json
    {
        "sso_redirect_options": {
            "immediate": false,
            "on_welcome_page": true,
            "on_login_page": true
        }
    }
    It is most common to use the immediate flag instead of on_welcome_page.

Native OIDC

Static OIDC Client IDs are preferred and can be specified under oidc_static_clients as a mapping from issuer to configuration object containing client_id.
Issuer must have a trailing forward slash. As an example:

json
{
    "oidc_static_clients": {
        "https://auth.example.com/": {
            "client_id": "example-client-id"
        }
    }
}

If a matching static client is not found, the app will attempt to dynamically register a client using metadata specified under oidc_metadata.
The app has sane defaults for the metadata properties below but on stricter policy identity providers they may not pass muster, e.g. contacts may be required.
The following subproperties are available:

  1. client_uri: This is the base URI for the OIDC client registration, typically logo_uri, tos_uri, and policy_uri must be either on the same domain or a subdomain of this URI.
  2. logo_uri: Optional URI for the client logo.
  3. tos_uri: Optional URI for the client's terms of service.
  4. policy_uri: Optional URI for the client's privacy policy.

As an example:

json
{
    "oidc_metadata": {
        "client_uri": "https://example.com",
        "logo_uri": "https://example.com/logo.png",
        "tos_uri": "https://example.com/tos",
        "policy_uri": "https://example.com/policy"
    }
}

VoIP / Jitsi calls

Currently, Element uses Jitsi to offer conference calls in rooms, with an experimental Element Call implementation in the works.
A set of defaults are applied, pointing at our Jitsi and Element Call instances, to ensure conference calling works, however you
can point Element at your own if you prefer.

More information about the Jitsi setup can be found here.

The VoIP and Jitsi options are:

  1. jitsi: Optional configuration for how to start Jitsi conferences. Currently can only contain a single preferred_domain
    value which points at the domain of the Jitsi instance. Defaults to meet.element.io. This is not used if the Jitsi widget
    was created by an integration manager, or if the homeserver provides Jitsi information in /.well-known/matrix/client. For
    example:
    json
    {
        "jitsi": {
            "preferred_domain": "meet.jit.si"
        }
    }
  2. jitsi_widget: Optional configuration for the built-in Jitsi widget. Currently can only contain a single skip_built_in_welcome_screen
    value, denoting whether the "Join Conference" button should be shown. When true (default false), Jitsi calls will skip to
    the call instead of having a screen with a single button on it. This is most useful if the Jitsi instance being used already
    has a landing page for users to test audio and video before joining the call, otherwise users will automatically join the call.
    For example:
    json
    {
        "jitsi_widget": {
            "skip_built_in_welcome_screen": true
        }
    }
  3. voip: Optional configuration for various VoIP features. Currently can only contain a single obey_asserted_identity value to
    send MSC3086-style asserted identity messages during VoIP calls in the room corresponding to the asserted identity. This must
    only be set in trusted environments. The option defaults to false. For example:
    json
    {
        "voip": {
            "obey_asserted_identity": false
        }
    }
  4. widget_build_url: Optional URL to have Element make a request to when a user presses the voice/video call buttons in the app,
    if a call would normally be started by the action. The URL will be called with a roomId query parameter to identify the room
    being called in. The URL must respond with a JSON object similar to the following:
    json
    {
        "widget_id": "$arbitrary_string",
        "widget": {
            "creatorUserId": "@user:example.org",
            "id": "$the_same_widget_id",
            "type": "m.custom",
            "waitForIframeLoad": true,
            "name": "My Widget Name Here",
            "avatar_url": "mxc://example.org/abc123",
            "url": "https://example.org/widget.html",
            "data": {
                "title": "Subtitle goes here"
            }
        },
        "layout": {
            "container": "top",
            "index": 0,
            "width": 65,
            "height": 50
        }
    }
    The widget is the content of a normal widget state event. The layout is the layout specifier for the widget being created,
    as defined by the io.element.widgets.layout state event. By default this applies to all rooms, but the behaviour can be skipped for
    2-person rooms, causing Element to fall back to 1:1 VoIP, by setting the option widget_build_url_ignore_dm to true.
  5. audio_stream_url: Optional URL to pass to Jitsi to enable live streaming. This option is considered experimental and may be removed
    at any time without notice.
  6. element_call: Optional configuration for native group calls using Element Call, with the following subkeys:
    • use_exclusively: A boolean specifying whether Element Call should be used exclusively as the only VoIP stack in
      the app, removing the ability to enable legacy 1:1 calls or Jitsi calls.
      It is a misconfiguration if its set to true while element_call.disable is also true!
      Defaults to false.
    • disable: A boolean flag specifying whether Element Call should be disabled.
      If true, element_call.use_exclusively has no effect!
      Defaults to false.
    • brand: Optional name for the app. Defaults to Element Call. This is
      used throughout the application in various strings/locations.
    • guest_spa_url: Optional URL for an Element Call single-page app (SPA),
      for guest links. If this is set, Element Web will expose a "join" link
      for public video rooms, which can then be shared to non-matrix users.
      The target Element Call SPA is typically set up to use a homeserver that
      allows users to register without email ("passwordless guest users") and to
      federate.

Bug reporting

If you run your own rageshake server to collect bug reports, the following options may be of interest:

  1. bug_report_endpoint_url: URL for where to submit rageshake logs to. Rageshakes include feedback submissions and bug reports. When
    not present in the config, the app will disable all rageshake functionality. Set to https://rageshakes.element.io/api/submit to submit
    rageshakes to us, or use your own rageshake server.
    You may also set the value to "local" if you wish to only store logs locally, in order to download them for debugging.
  2. existing_issues_url: URL for where to find existing issues.
  3. new_issue_url: URL for where to submit new issues.

If you would like to use Sentry for rageshake data, add a sentry object to your config with the following values:

  1. dsn: The Sentry DSN.
  2. environment: Optional environment to pass to Sentry.

For example:

json
{
    "sentry": {
        "dsn": "dsn-goes-here",
        "environment": "production"
    }
}

Integration managers

Integration managers are embedded applications within Element to help the user configure bots, bridges, and widgets. An integration manager
is a separate piece of software not typically available with your homeserver. To disable integrations, set the options defined here to null.

  1. integrations_ui_url: The UI URL for the integration manager.
  2. integrations_rest_url: The REST interface URL for the integration manager.
  3. integrations_widgets_urls: A list of URLs the integration manager uses to host widgets.

If you would like to use Scalar, the integration manager maintained by Element, the following options would apply:

json
{
    "integrations_ui_url": "https://scalar.vector.im/",
    "integrations_rest_url": "https://scalar.vector.im/api",
    "integrations_widgets_urls": [
        "https://scalar.vector.im/_matrix/integrations/v1",
        "https://scalar.vector.im/api",
        "https://scalar-staging.vector.im/_matrix/integrations/v1",
        "https://scalar-staging.vector.im/api"
    ]
}

For widgets in general (from an integration manager or not) there is also:

  • default_widget_container_height

This controls the height that the top widget panel initially appears as and is the height in pixels, default 280.

Administrative options

If you would like to include a custom message when someone is reporting an event, set the following Markdown-capable field:

json
{
    "report_event": {
        "admin_message_md": "Please be sure to review our [terms of service](https://example.org/terms) before reporting a message."
    }
}

To add additional "terms and conditions" links throughout the app, use the following template:

json
{
    "terms_and_conditions_links": [{ "text": "Code of conduct", "url": "https://example.org/code-of-conduct" }]
}

Analytics

To configure Posthog, add the following under posthog in your config:

  1. api_host: The hostname of the posthog server.
  2. project_api_key: The API key from posthog.

When these configuration options are not present,
analytics are deemed impossible and the user won't be asked to opt in to the system.

There are additional root-level options which can be specified:

  1. analytics_owner: the company name used in dialogs talking about analytics - this defaults to brand,
    and is useful when the provider of analytics is different from the provider of the Element instance.
  2. privacy_policy_url: URL to the privacy policy including the analytics collection policy.

Miscellaneous

Element supports other options which don't quite fit into other sections of this document.

To configure whether presence UI is shown for a given homeserver, set enable_presence_by_hs_url. It is recommended to
set this value to the following at a minimum:

json
{
    "enable_presence_by_hs_url": {
        "https://matrix.org": false,
        "https://matrix-client.matrix.org": false
    }
}

Identity servers

The identity server is used for inviting other users to a room via third party
identifiers like emails and phone numbers. It is not used to store your password
or account information.

As of Element 1.4.0, all identity server functions are optional and you are
prompted to agree to terms before data is sent to the identity server.

Element will check multiple sources when looking for an identity server to use in
the following order of preference:

  1. The identity server set in the user's account data
    • For a new user, no value is present in their account data. It is only set
      if the user visits Settings and manually changes their identity server.
  2. The identity server provided by the .well-known lookup that occurred at
    login
  3. The identity server provided by the Riot config file

If none of these sources have an identity server set, then Element will prompt the
user to set an identity server first when attempting to use features that
require one.

Currently, the only two public identity servers are https://vector.im and
https://matrix.org, however in the future identity servers will be
decentralised.

Desktop app configuration

See https://github.com/element-hq/element-web/blob/develop/apps/desktop/README.md#user-specified-configjson

UI Features

Parts of the UI can be disabled using UI features. These are settings which appear
under setting_defaults and can only be true (default) or false. When false,
parts of the UI relating to that feature will be disabled regardless of the user's
preferences.

Currently, the following UI feature flags are supported:

  • UIFeature.urlPreviews - Whether URL previews are enabled across the entire application.
  • UIFeature.feedback - Whether prompts to supply feedback are shown.
  • UIFeature.voip - Whether or not VoIP is shown readily to the user. When disabled,
    Jitsi widgets will still work though they cannot easily be added.
  • UIFeature.widgets - Whether or not widgets will be shown.
  • UIFeature.advancedSettings - Whether or not sections titled "advanced" in room and
    user settings are shown to the user.
  • UIFeature.shareQrCode - Whether or not the QR code on the share room/event dialog
    is shown.
  • UIFeature.shareSocial - Whether or not the social icons on the share room/event dialog
    are shown.
  • UIFeature.identityServer - Whether or not functionality requiring an identity server
    is shown. When disabled, the user will not be able to interact with the identity
    server (sharing email addresses, 3PID invites, etc).
  • UIFeature.thirdPartyId - Whether or not UI relating to third party identifiers (3PIDs)
    is shown. Typically this is considered "contact information" on the homeserver, and is
    not directly related to the identity server.
  • UIFeature.registration - Whether or not the registration page is accessible. Typically
    useful if accounts are managed externally.
  • UIFeature.passwordReset - Whether or not the password reset page is accessible. Typically
    useful if accounts are managed externally.
  • UIFeature.deactivate - Whether or not the deactivate account button is accessible. Typically
    useful if accounts are managed externally.
  • UIFeature.advancedEncryption - Whether or not advanced encryption options are shown to the
    user.
  • UIFeature.roomHistorySettings - Whether or not the room history settings are shown to the user.
    This should only be used if the room history visibility options are managed by the server.
  • UIFeature.TimelineEnableRelativeDates - Display relative date separators (eg: 'Today', 'Yesterday') in the
    timeline for recent messages. When false day dates will be used.
  • UIFeature.locationSharing - Whether or not location sharing menus will be shown.
  • UIFeature.allowCreatingPublicRooms - Whether or not public rooms can be created.
  • UIFeature.allowCreatingPublicSpaces - Whether or not public spaces can be created.

Modules

modules: An optional array of module paths to load at runtime. Each entry is a URL or path to a JavaScript module entry point that will be dynamically imported when Element Web starts.

Note: This is separate from the build-time module system configured via build_config.yaml. Runtime modules are loaded dynamically from the paths specified in config.json, while build-time modules are bundled during compilation.

Example:

json
{
    "modules": ["https://example.com/my-module.js", "/path/to/local-module.js"]
}

Each module URL is loaded using dynamic import (import()). The modules are loaded in order after Element Web initializes but before the application fully starts. Modules must be accessible from the browser and should export a compatible module format that works with the Module API.

Undocumented / developer options

The following are undocumented or intended for developer use only.

  1. fallback_hs_url
  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.
  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.
This config can be overwritten by the end using by creating a config.json file at the paths described here.

After changing the config, the app will need to be exited fully (including via the task tray) and re-started.


Custom Home (`docs/custom-home.md`)

Custom Home Page

The home page is shown whenever the user is logged in, but no room is selected.
A custom home.html replacing the default home page can be configured either in .well-known/matrix/client or config.json.
Such a custom home page can be used to communicate helpful information and important rules to the users.

Configuration

To provide a custom home page for all element-web/desktop users of a homeserver, include the following in .well-known/matrix/client:

text
{
    "io.element.embedded_pages": {
        "home_url": "https://example.org/home.html"
    }
}

The home page can be overridden in config.json to provide all users of an element-web installation with the same experience:

text
{
    "embeddedPages": {
        "homeUrl": "https://example.org/home.html"
    }
}

`home.html` Example

The following is a simple example for a custom home.html:

text
<style type="text/css">
	.tos {
		width: auto;
		color: black;
		background : #ffcccb;
		font-weight: bold;
	}
</style>

<h1>The example.org Matrix Server</h1>

<div class="tos">
	<p>Behave appropriately.</p>
</div>

<h2>Start Chatting</h2>
<ul>
	<li><a href="#/dm">Send a Direct Message</a></li>
	<li><a href="#/directory">Explore Public Rooms</a></li>
	<li><a href="#/new">Create a Group Chat</a></li>
</ul>

When choosing colors, be aware that the home page may be displayed in either light or dark mode.

It may be needed to set CORS headers for the home.html to enable element-desktop to fetch it, with e.g., the following nginx config:

text
add_header Access-Control-Allow-Origin *;

Debugging (`docs/debugging.md`)

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
  2. Start element with the --inspect-brk flag
  3. 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:

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


E2ee (`docs/e2ee.md`)

End to end encryption by default

By default, Element will create encrypted DM rooms if the user you are chatting with has keys uploaded on their account.
For private room creation, Element will default to encryption on but give you the choice to opt-out.

Disabling encryption by default

Set the following on your homeserver's
/.well-known/matrix/client config:

json
{
    "io.element.e2ee": {
        "default": false
    }
}

Disabling encryption

Set the following on your homeserver's
/.well-known/matrix/client config:

json
{
    "io.element.e2ee": {
        "force_disable": true
    }
}

When force_disable is true:

  • all rooms will be created with encryption disabled, and it will not be possible to enable
    encryption from room settings.
  • any io.element.e2ee.default value will be disregarded.

Note: If the server is configured to forcibly enable encryption for some or all rooms,
this behaviour will be overridden.

Setting up recovery

By default, Element strongly encourages (but does not require) users to set up
recovery so that you can access history on your new devices as well as retain access to your message history and cryptographic identity when you lose all of your devices.

Removal of old settings

Support for the configuration options secure_backup_required and secure_backup_setup_methods
in the /.well-known/matrix/client config has been removed.

Setting up recovery is now always recommended to all users by showing a one-off toast and a
permanent red dot on the Encryption tab in the Settings dialog. When creating a new
recovery key, the UI only supports auto-generated keys. Using an existing (custom) passphrase
still works, but is not exposed in the UI when setting up recovery.

Compatibility

The settings above were first proposed under a im.vector.riot.e2ee key, which
is now deprecated. Element will check for either key, preferring
io.element.e2ee if both exist.


Feature Flags (`docs/feature-flags.md`)

Feature flags

When developing new features for Element, we use feature flags to give us more
flexibility and control over when and where those features are enabled.

For example, flags make the following things possible:

  • Extended testing of a feature via labs on develop
  • Enabling features when ready instead of the first moment the code is released
  • Testing a feature with a specific set of users (by enabling only on a specific
    Element instance)

The size of the feature controlled by a feature flag may vary widely: it could
be a large project like reactions or a smaller change to an existing algorithm.
A large project might use several feature flags if it's useful to control the
deployment of different portions independently.

Everyone involved in a feature (engineering, design, product, reviewers) should
think about its deployment plan up front as best as possible so we can have the
right feature flags in place from the start.

Interaction with spec process

Historically, we have often used feature flags to guard client features that
depend on unstable spec features. Unfortunately, there was never clear agreement
about how long such a flag should live for, when it should be removed, etc.

Under the new spec
process
, server-side
unstable features can be used by clients and enabled by default as long as
clients commit to doing the associated clean up work once a feature stabilises.

Starting work on a feature

When starting work on a feature, we should create a matching feature flag:

  1. Add a new
    setting
    of the form:
js
"feature_cats": {
        isFeature: true,
        displayName: _td("Adds cats everywhere"),
        supportedLevels: LEVELS_FEATURE,
        default: false,
    },
  1. Check whether the feature is enabled as appropriate:
js
SettingsStore.getValue("feature_cats");
  1. Document the feature in the labs documentation

With these steps completed, the feature is disabled by default, but can be
enabled on develop and nightly by interested users for testing.

Different features may have different deployment plans for when to enable where.
The following lists a few common options.

Enabling by default on develop and nightly

Set the feature to true in the
develop
and
nightly
configs:

json
"features": {
        "feature_cats": true
    },

Enabling by default on staging, app, and release

Set the feature to true in the
staging / app
and
release
configs.

Note: The above will only enable the feature for https://app.element.io and official Element
Desktop builds. It will not be enabled for self-hosted installed, custom desktop builds, etc. To
cover these cases, change the setting's default in Settings.tsx to true.

Feature deployed successfully

Once we're confident that a feature is working well, we should remove or convert the flag.

If the feature is meant to be turned off/on by the user:

  1. Remove isFeature from the setting
  2. Change the default to true (if desired).
  3. Remove the feature from the labs documentation
  4. Celebrate! 🥳

If the feature is meant to be forced on (non-configurable):

  1. Remove the setting
  2. Remove all getValue lines that test for the feature.
  3. Remove the feature from the labs documentation
  4. If applicable, remove the feature state from
    develop,
    nightly,
    staging / app,
    and
    release
    configs
  5. Celebrate! 🥳

Gdb (`docs/gdb.md`)

Using gdb against Element-Desktop

Occasionally it is useful to be able to connect to a running Element-Desktop
with 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
    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
    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:

    text
    .
    ├── 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.


Icons (`docs/icons.md`)

Icons

Icons are loaded using @svgr/webpack.
This is configured in element-web.

Each .svg exports a ReactComponent at the named export Icon.
Icons have role="presentation" and aria-hidden automatically applied. These can be overriden by passing props to the icon component.

SVG file recommendations:

  • Colours should not be defined absolutely. Use currentColor instead.
  • SVG files should be taken from the design compound as they are. Some icons contain special padding.
    This means that there should be icons for each size, e.g. warning-16px and warning-32px.

Example usage:

text
import { Icon as FavoriteIcon } from 'res/img/element-icons/favorite.svg';

const MyComponent = () => {
    return <>
        <FavoriteIcon className="mx_Icon mx_Icon_16">
    </>;
}

If possible, use the icon classes from here.

Custom styling

Icon components are svg elements and may be custom styled as usual.

_MyComponents.pcss:

css
.mx_MyComponent-icon {
    height: 20px;
    width: 20px;

    * {
        fill: $accent;
    }
}

MyComponent.tsx:

typescript
import { Icon as FavoriteIcon } from 'res/img/element-icons/favorite.svg';

const MyComponent = () => {
    return <>
        <FavoriteIcon className="mx_MyComponent-icon" role="img" aria-hidden="false">
    </>;
}

Install (`docs/install.md`)

Installing Element Web

Familiarise yourself with the 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.
There are some exceptions like when using localhost, which is considered a secure context and thus allowed.

Release tarball

  1. Download the latest version from https://github.com/element-hq/element-web/releases
  2. Untar the tarball on your web server
  3. Move (or symlink) the element-x.x.x directory to an appropriate name
  4. Configure the correct caching headers in your webserver (see README.md)
  5. Configure the app by copying config.sample.json to config.json and
    modifying it. See the configuration docs for details.
  6. Enter the URL into your browser and log into Element!

Releases are signed using gpg and the OpenPGP standard,
and can be checked against the public key located at https://packages.element.io/element-release-key.asc.

Debian package

Element Web is now also available as a Debian package for Debian and Ubuntu based systems.

shell
sudo apt install -y wget apt-transport-https
sudo wget -O /usr/share/keyrings/element-io-archive-keyring.gpg https://packages.element.io/debian/element-io-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/element-io-archive-keyring.gpg] https://packages.element.io/debian/ default main" | sudo tee /etc/apt/sources.list.d/element-io.list
sudo apt update
sudo apt install element-web

Configure the app by modifying /etc/element-web/config.json. See the configuration docs for details.

Then point your chosen web server (e.g. Caddy, Nginx, Apache, etc) at the /usr/share/element-web webroot.

Docker

The Docker image can be used to serve element-web as a web server. The easiest way to use
it is to use the prebuilt image:

bash
docker run --rm -p 127.0.0.1:80:80 vectorim/element-web

A server can also be made available to clients outside the local host by omitting the
explicit local address as described in
docker run documentation:

bash
docker run --rm -p 80:80 vectorim/element-web

To supply your own custom config.json, map a volume to /app/config.json. For example,
if your custom config was located at /etc/element-web/config.json then your Docker command
would be:

bash
docker run --rm -p 127.0.0.1:80:80 -v /etc/element-web/config.json:/app/config.json vectorim/element-web

The Docker image is configured to run as an unprivileged (non-root) user by
default. This should be fine on modern Docker runtimes, but binding to port 80
on other runtimes may require root privileges. To resolve this, either run the
image as root (docker run --user 0) or, better, change the port that nginx
listens on via the ELEMENT_WEB_PORT environment variable.

Element Web Modules can be dynamically loaded
by being made available (e.g. via bind mount) in a directory within /modules/.
The default entrypoint will be index.js in that directory but can be overridden if a package.json file is found with a main directive.
These modules will be presented in a /modules subdirectory within the webroot, and automatically added to the config.json modules field.

If you wish to use docker in read-only mode,
you should follow the upstream instructions
but additionally include the following directories:

  • /tmp/
  • /etc/nginx/conf.d/

The behaviour of the docker image can be customised via the following
environment variables:

  • ELEMENT_WEB_PORT

    The port to listen on (within the docker container) for HTTP
    traffic. Defaults to 80.

Building the docker image

To build the image yourself:

bash
git clone https://github.com/element-hq/element-web.git element-web
cd element-web
git checkout master
docker build .

If you're building a custom branch, or want to use the develop branch, check out the appropriate
element-web branch and then run:

bash
docker build -t \
    --build-arg USE_CUSTOM_SDKS=true \
    --build-arg JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git" \
    --build-arg JS_SDK_BRANCH="develop" \
    .

Kubernetes

The provided element-web docker image can also be run from within a Kubernetes cluster.
See the Kubernetes example for more details.


Jitsi Dev (`docs/jitsi-dev.md`)

Jitsi wrapper developer docs

If you're looking for information on how to set up Jitsi in your Element, see
jitsi.md instead.

These docs are for developers wondering how the different conference buttons work
within Element. If you're not a developer, you're probably looking for jitsi.md.

Brief introduction to widgets

Widgets are embedded web applications in a room, controlled through state events, and
have a url property. They are largely specified by MSC1236
and have extensions proposed under MSC1286.

The url is typically something we shove into an iframe with sandboxing (see AppTile
in the react-sdk), though for some widgets special integration can be done. v2 widgets
have a data object which helps achieve that special integration, though v1 widgets
are best iframed and left alone.

Widgets have a postMessage API they can use to interact with Element, which also allows
Element to interact with them. Typically this is most used by the sticker picker (an
account-level widget), though widgets like the Jitsi widget will request permissions to
get 'stuck' into the room list during a conference.

Widgets can be added with the /addwidget command.

Brief introduction to integration managers

Integration managers (like Scalar and Dimension) are accessible via the 4 squares in
the top right of the room and provide a simple UI over top of bridges, bots, and other
stuff to plug into a room. They are a separate service to Element and are thus iframed
in a dialog as well. They also have a postMessage API they can use to interact with
the client to create things like widgets, give permissions to bridges, and generally
set everything up for the integration the user is working with.

Integration managers do not currently have a spec associated with them, though efforts
are underway in MSC1286.

Widgets configured by integration managers

Integration managers will often "wrap" a widget by using a widget url which points
to the integration manager instead of to where the user requested the widget be. For
example, a custom widget added in an integration manager for https://matrix.org will
end up creating a widget with a URL like https://integrations.example.org?widgetUrl=https%3A%2F%2Fmatrix.org.

The integration manager's wrapper will typically have another iframe to isolate the
widget from the client by yet another layer. The wrapper often provides other functionality
which might not be available on the embedded site, such as a fullscreen button or the
communication layer with the client (all widgets should be talking to the client
over postMessage, even if they aren't going to be using the widget APIs).

Widgets added with the /addwidget command will not be wrapped as they are not going
through an integration manager. The widgets themselves should also work outside of
Element. Widgets currently have a "pop out" button which opens them in a new tab and
therefore have no connection back to Riot.

Jitsi widgets from integration managers

Integration managers will create an entire widget event and send it over postMessage
for the client to add to the room. This means that the integration manager gets to
decide the conference domain, conference name, and other aspects of the widget. As
a result, users can end up with a Jitsi widget that does not use the same conference
server they specified in their config.json - this is expected.

Some integration managers allow the user to change the conference name while others
will generate one for the user.

Jitsi widgets generated by Element itself

When the user clicks on the call buttons by the composer, the integration manager is
not involved in the slightest. Instead, Element itself generates a widget event, this time
using the config.json parameters, and publishes that to the room. If there's only two
people in the room, a plain WebRTC call is made instead of using a widget at all - these
are defined in the Matrix specification.

The Jitsi widget created by Element uses a local jitsi.html wrapper (or one hosted by
https://app.element.io for desktop users or those on non-https domains) as the widget
url. The wrapper has some basic functionality for talking to Element to ensure the
required postMessage calls are fulfilled.

Note: Per jitsi.md the preferredDomain can also come from the server's
client .well-known data.

The Jitsi wrapper in Element

Whenever Element sees a Jitsi widget, it ditches the url and instead replaces it with
its local wrapper, much like what it would do when creating a widget. However, instead
of using one from app.element.io, it will use one local to the client instead.

The wrapper is used to provide a consistent experience to users, as well as being faster
and less risky to load. The local wrapper URL is populated with the conference information
from the original widget (which could be a v1 or v2 widget) so the user joins the right
call.

Critically, when the widget URL is reconstructed it does not take into account the
config.json's preferredDomain for Jitsi. If it did this, users would end up on different
conference servers and therefore different calls entirely.

Note: Per jitsi.md the preferredDomain can also come from the server's
client .well-known data.


Jitsi (`docs/jitsi.md`)

Jitsi in Element

Element uses Jitsi for conference calls, which provides options for
self-hosting your own server and supports most major platforms.

1:1 calls, or calls between you and one other person, do not use Jitsi. Instead, those
calls work directly between clients or via TURN servers configured on the respective
homeservers.

There's a number of ways to start a Jitsi call: the easiest way is to click on the
voice or video buttons near the message composer in a room with more than 2 people. This
will add a Jitsi widget which allows anyone in the room to join.

Integration managers (available through the 4 squares in the top right of the room) may
provide their own approaches for adding Jitsi widgets.

Configuring Element to use your self-hosted Jitsi server

You can host your own Jitsi server to use with Element. It's usually advisable to use a recent
version of Jitsi. In particular, versions older than around 6826 will cause problems with
Element 1.9.10 or newer.

Element will use the Jitsi server that is embedded in the widget, even if it is not the
one you configured. This is because conference calls must be held on a single Jitsi
server and cannot be split over multiple servers.

However, you can configure Element to start a conference with your Jitsi server by adding
to your config the following:

json
{
    "jitsi": {
        "preferred_domain": "your.jitsi.example.org"
    }
}

Element's default is meet.element.io (a free service offered by Element). meet.jit.si
is an instance hosted by Jitsi themselves and is also free to use.

Once you've applied the config change, refresh Element and press the call button. This
should start a new conference on your Jitsi server.

Note: The widget URL will point to a jitsi.html page hosted by Element. The Jitsi
domain will appear later in the URL as a configuration parameter.

Hint: If you want everyone on your homeserver to use the same Jitsi server by
default, and you are using element-web 1.6 or newer, set the following on your homeserver's
/.well-known/matrix/client config:

json
{
    "im.vector.riot.jitsi": {
        "preferredDomain": "your.jitsi.example.org"
    }
}

Element Android

Element Android (1.0.5+) supports custom Jitsi domains, similar to Element Web above.

1:1 calls, or calls between you and one other person, do not use Jitsi. Instead, those
calls work directly between clients or via TURN servers configured on the respective
homeservers.

For rooms with more than 2 joined members, when creating a Jitsi conference via call/video buttons of the toolbar (not via integration manager), Element Android will create a widget using the wrapper hosted on app.element.io.
The domain used is the one specified by the /.well-known/matrix/client endpoint, and if not present it uses the fallback defined in config.json (meet.element.io)

For active Jitsi widgets in the room, a native Jitsi widget UI is created and points to the instance specified in the domain key of the widget content data.

Element Android manages allowed native widgets permissions a bit differently than web widgets (as the data shared are different and never shared with the widget URL). For Jitsi widgets, permissions are requested only once per domain (consent saved in account data).

Jitsi Wrapper

Note: These are developer docs. Please consult your client's documentation for
instructions on setting up Jitsi.

The react-sdk wraps all Jitsi call widgets in a local wrapper called jitsi.html
which takes several parameters:

Query string:

  • widgetId: The ID of the widget. This is needed for communication back to the
    react-sdk.
  • parentUrl: The URL of the parent window. This is also needed for
    communication back to the react-sdk.

Hash/fragment (formatted as a query string):

  • conferenceDomain: The domain to connect Jitsi Meet to.
  • conferenceId: The room or conference ID to connect Jitsi Meet to.
  • isAudioOnly: Boolean for whether this is a voice-only conference. May not
    be present, should default to false.
  • startWithAudioMuted: Boolean for whether the calls start with audio
    muted. May not be present.
  • startWithVideoMuted: Boolean for whether the calls start with video
    muted. May not be present.
  • displayName: The display name of the user viewing the widget. May not
    be present or could be null.
  • avatarUrl: The HTTP(S) URL for the avatar of the user viewing the widget. May
    not be present or could be null.
  • userId: The MXID of the user viewing the widget. May not be present or could
    be null.

The react-sdk will assume that jitsi.html is at the path of wherever it is currently
being served. For example, https://develop.element.io/jitsi.html or vector://webapp/jitsi.html.

The jitsi.html wrapper can use the react-sdk's WidgetApi to communicate, making
it easier to actually implement the feature.


Kubernetes (`docs/kubernetes.md`)

Running in Kubernetes

In case you would like to deploy element-web in a kubernetes cluster you can use
the provided Kubernetes example below as a starting point. Note that this example assumes the
Nginx ingress to be installed.

Note that the content of the required config.json is defined inside this yaml because it needs
to be put in your Kubernetes cluster as a ConfigMap.

So to use it you must create a file with this content as a starting point and modify it so it meets
the requirements of your environment.

Then you can deploy it to your cluster with something like kubectl apply -f my-element-web.yaml.

text
# This is an example of a POSSIBLE config for deploying a single element-web instance in Kubernetes

# Use the element-web namespace to put it all in.

apiVersion: v1
kind: Namespace
metadata:
  name: element-web

---

# The config.json file is to be put into Kubernetes as a config file in such a way that
# the element web instance can read it.
# The code below shows how this can be done with the config.sample.json content.

apiVersion: v1
kind: ConfigMap
metadata:
  name: element-config
  namespace: element-web
data:
  config.json: |
    {
        "default_server_config": {
            "m.homeserver": {
                "base_url": "https://matrix-client.matrix.org",
                "server_name": "matrix.org"
            },
            "m.identity_server": {
                "base_url": "https://vector.im"
            }
        },
        "disable_custom_urls": false,
        "disable_guests": false,
        "disable_login_language_selector": false,
        "disable_3pid_login": false,
        "brand": "Element",
        "integrations_ui_url": "https://scalar.vector.im/",
        "integrations_rest_url": "https://scalar.vector.im/api",
        "integrations_widgets_urls": [
                "https://scalar.vector.im/_matrix/integrations/v1",
                "https://scalar.vector.im/api",
                "https://scalar-staging.vector.im/_matrix/integrations/v1",
                "https://scalar-staging.vector.im/api"
        ],
        "bug_report_endpoint_url": "https://rageshakes.element.io/api/submit",
        "defaultCountryCode": "GB",
        "show_labs_settings": false,
        "features": { },
        "default_federate": true,
        "default_theme": "light",
        "room_directory": {
            "servers": [
                    "matrix.org"
            ]
        },
        "enable_presence_by_hs_url": {
            "https://matrix.org": false,
            "https://matrix-client.matrix.org": false
        },
        "setting_defaults": {
            "breadcrumbs": true
        },
        "jitsi": {
            "preferred_domain": "meet.element.io"
        }
    }


---

# A deployment of the element-web for a single instance

apiVersion: apps/v1
kind: Deployment
metadata:
  name: element
  namespace: element-web
spec:
  selector:
    matchLabels:
      app: element
  replicas: 1
  template:
    metadata:
      labels:
        app: element
    spec:
      containers:
      - name: element
        image: vectorim/element-web:latest
        volumeMounts:
        - name: config-volume
          mountPath: /app/config.json
          subPath: config.json
        ports:
        - containerPort: 80
          name: element
          protocol: TCP
        readinessProbe:
            httpGet:
                path: /
                port: element
            initialDelaySeconds: 2
            periodSeconds: 3
        livenessProbe:
            httpGet:
                path: /
                port: element
            initialDelaySeconds: 10
            periodSeconds: 10
      volumes:
      - name: config-volume
        configMap:
          name: element-config

---

# Wrap it all in a Service

apiVersion: v1
kind: Service
metadata:
  name: element
  namespace: element-web
spec:
  selector:
    app: element
  ports:
    - name: default
      protocol: TCP
      port: 80
      targetPort: 80

---

# An ingress definition to expose the service via a hostname

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: element
  namespace: element-web
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/configuration-snippet: |
      add_header X-Frame-Options SAMEORIGIN;
      add_header X-Content-Type-Options nosniff;
      add_header X-XSS-Protection "1; mode=block";
      add_header Content-Security-Policy "frame-ancestors 'self'";
spec:
  rules:
    - host: element.example.nl
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: element
                port:
                  number: 80

---

Labs (`docs/labs.md`)

Labs features

If Labs is enabled in the Element config, you can enable some of these features by going
to Settings->Labs. This list is non-exhaustive and subject to change, chat in
#element-web:matrix.org for more information.

If a labs features gets more stable, it may be promoted to a beta feature
(see Betas).

Be warned! Labs features are not finalised, they may be fragile, they may change, they may be
dropped. Ask in the room if you are unclear about any details here.

Render LaTeX maths in messages (`feature_latex_maths`)

Enables rendering of LaTeX maths in messages using KaTeX. LaTeX between single dollar-signs is interpreted as inline maths and double dollar-signs as display maths (i.e. centred on its own line).

Message pinning (`feature_pinning`)

Allows you to pin messages in the room. To pin a message, use the 3 dots to the right of the message
and select "Pin".

Jump to date (`feature_jump_to_date`)

Note: This labs feature is only visible when your homeserver has MSC3030 enabled
(in Synapse, add experimental_features -> msc3030_enabled to your
homeserver.yaml) which means GET /_matrix/client/versions responds with
org.matrix.msc3030 under the unstable_features key.

Adds a dropdown menu to the date separator headers in the timeline which allows
you to jump to last week, last month, the beginning of the room, or choose a
date from the calendar.

Also adds the /jumptodate 2022-01-31 slash command.

New ways to ignore people (`feature_mjolnir`)

When enabled, a new settings tab appears for users to be able to manage their ban lists.
This is a different kind of ignoring where the ignored user's messages still get rendered,
but are hidden by default.

Ban lists are rooms within Matrix, proposed as MSC2313.
Mjolnir is a set of moderation tools which support
ban lists.

Verifications in DMs (`feature_dm_verification`)

An implementation of MSC2241. When enabled, verification might not work with devices which don't support MSC2241.

This also includes a new implementation of the user & member info panel, designed to share more code between showing community members & room members. Built on top of this new panel is also a new UX for verification from the member panel.

The setting will be removed in a future release, enabling it non-optionally for
all users.

Bridge info tab (`feature_bridge_state`)

Adds a "Bridge Info" tab to the Room Settings dialog, if a compatible bridge is
present in the room. The Bridge info tab pulls information from the m.bridge state event (MSC2346). Since the feature is based upon a MSC, most
bridges are not expected to be compatible, and users should not rely on this
tab as the single source of truth just yet.

Live location sharing (`feature_location_share_live`) [In Development]

Enables sharing your current location to the timeline, with live updates.

Video rooms (`feature_video_rooms`) [Beta]

Enables support for creating video rooms, which are persistent video chats that users can jump in and out of.

Element Call video rooms (`feature_element_call_video_rooms`) [In Development]

Enables support for video rooms that use Element Call rather than Jitsi, and causes the 'New video room' option to create Element Call video rooms rather than Jitsi ones.

This flag will not have any effect unless feature_video_rooms is also enabled.

Disable per-sender encryption for Element Call (`feature_disable_call_per_sender_encryption`)

The default for embedded Element Call in Element Web is per-participant encryption.
This labs flag disables encryption for embedded Element Call in encrypted rooms.

Under the hood this stops Element Web from adding the perParticipantE2EE flag for the Element Call widget url.

This is useful while we experiment with encryption and to make calling compatible with platforms that don't use encryption yet.

Enable the notifications panel in the room header (`feature_notifications`)

Unreliable in encrypted rooms.

Knock rooms (`feature_ask_to_join`) [In Development]

Enables knock feature for rooms. This allows users to ask to join a room.

Exclude insecure devices when sending/receiving messages (`feature_exclude_insecure_devices`)

Do not send or receive messages to/from devices that are not properly verified. Users with unverified devices will not
receive your messages at all on those devices, and if they send messages, you will not be able to read them, but you
will be aware that a message exists.

Encrypted state events (MSC4362) (`feature_msc4362_encrypted_state_events`)

Encrypt most of the state events in the room, including the room name and topic.

WARNING: this means that users joining a room who do not have access to its history will not be able to see the name or
topic of the room, or any other room state information. It also means the room name and topic are not available before
joining a room.

New notifications settings (`feature_notification_settings2`) [Beta]

Replaces the legacy notification settings with a new one to manage push rules.

User status (`feature_user_status`)

Enables setting a status message in your profile and to be able to view other's statuses.
Requires MSC4429 and MSC4426.

Warning This feature has options which are not backwards compatible, disabling
it may have unintended consequences.

Log in with QR (`feature_login_with_qr`)

Enables logging in to Element Web/Desktop by using Element X to scan a QR code.
Requires server support, based on the v2024 edition of MSC4108.
Can only be configured via config.json, as labs flags cannot be set until after login, and are cleared on log out. The UI option is disabled.
Note, this does not affect the existing Link new device flow using the same MSC.

URL Preview Bundle (MSC4095) (`feature_msc4095_url_preview_bundle`)

Attaches URL preview information generated by the homeserver on messages sent.

Element Call React Component (`feature_element_call_react`)

Renders Element Call as a React component instead of a widget.


Local Echo Dev (`docs/local-echo-dev.md`)

Local echo (developer docs)

The React SDK provides some local echo functionality to allow for components to do something
quickly and fall back when it fails. This is all available in the local-echo directory within
stores.

Echo is handled in EchoChambers, with GenericEchoChamber being the base implementation for all
chambers. The EchoChamber class is provided as semantic access to a GenericEchoChamber
implementation, such as the RoomEchoChamber (which handles echoable details of a room).

Anything that can be locally echoed will be provided by the GenericEchoChamber implementation.
The echo chamber will also need to deal with external changes, and has full control over whether
or not something has successfully been echoed.

An EchoContext is provided to echo chambers (usually with a matching type: RoomEchoContext
gets provided to a RoomEchoChamber for example) with details about their intended area of
effect, as well as manage EchoTransactions. An EchoTransaction is simply a unit of work that
needs to be locally echoed.

The EchoStore manages echo chamber instances, builds contexts, and is generally less semantically
accessible than the EchoChamber class. For separation of concerns, and to try and keep things
tidy, this is an intentional design decision.

Note: The local echo stack uses a "whenable" pattern, which is similar to thenables and
EventEmitter. Whenables are ways of actioning a changing condition without having to deal
with listeners being torn down. Once the reference count of the Whenable causes garbage collection,
the Whenable's listeners will also be torn down. This is accelerated by the IDestroyable interface
usage.

Audit functionality

The UI supports a "Server isn't responding" dialog which includes a partial audit log-like
structure to it. This is partially the reason for added complexity of EchoTransactions
and EchoContexts - this information feeds the UI states which then provide direct retry
mechanisms.

The EchoStore is responsible for ensuring that the appropriate non-urgent toast (lower left)
is set up, where the dialog then drives through the contexts and transactions.


Media Handling (`docs/media-handling.md`)

Media handling

Surely media should be as easy as just putting a URL into an img and calling it good, right?
Not quite. Matrix uses something called a Matrix Content URI (better known as MXC URI) to identify
content, which is then converted to a regular HTTPS URL on the homeserver. However, sometimes that
URL can change depending on deployment considerations.

The react-sdk features a customisation endpoint
for media handling where all conversions from MXC URI to HTTPS URL happen. This is to ensure that
those obscure deployments can route all their media to the right place.

For development, there are currently two functions available: mediaFromMxc and mediaFromContent.
The mediaFromMxc function should be self-explanatory. mediaFromContent takes an event content as
a parameter and will automatically parse out the source media and thumbnail. Both functions return
a Media object with a number of options on it, such as getting various common HTTPS URLs for the
media.

It is extremely important that all media calls are put through this customisation endpoint. So
much so it's a lint rule to avoid accidental use of the wrong functions.


Memory Profiles And Leaks (`docs/memory-profiles-and-leaks.md`)

Memory leaks

Element usually emits slow behaviour just before it is about to crash. Getting a
memory snapshot (below) just before that happens is ideal in figuring out what
is going wrong.

Common symptoms are clicking on a room and it feels like the tab froze and scrolling
becoming jumpy/staggered.

If you receive a white screen (electron) or the chrome crash page, it is likely
run out of memory and it is too late for a memory profile. Please do report when
this happens though so we can try and narrow down what might have gone wrong.

Memory profiles/snapshots

When investigating memory leaks/problems it's usually important to compare snapshots
from different points in the Element session lifecycle. Most importantly, a snapshot
to establish the baseline or "normal" memory usage is useful. Taking a snapshot
roughly 30-60 minutes after starting Element is a good time to establish "normal"
memory usage for the app - anything after that is at risk of hiding the memory leak
and anything newer is still in the warmup stages of the app.

Memory profiles can contain sensitive information. If you are submitting a memory
profile to us for debugging purposes, please pick the appropriate Element developer and
send them over an encrypted private message. Do not share your memory profile in
public channels or with people you do not trust.

Taking a memory profile (Firefox)

  1. Press CTRL+SHIFT+I (I as in eye).
  2. Click the Memory tab.
  3. Press the camera icon in the top left of the pane.
  4. Wait a bit (coffee is a good option).
  5. When the save button appears on the left side of the panel, click it to save the
    profile locally.
  6. Compress the file (gzip or regular zip) to make the file smaller.
  7. Send the compressed file to whoever asked for it (if you trust them).

While the profile is in progress, the tab might be frozen or unresponsive.

Taking a memory profile (Chrome/Desktop)

  1. Press CTRL+SHIFT+I (I as in eye).
  2. Click the Memory tab.
  3. Select "Heap Snapshot" and the app.element.io VM instance (not the indexeddb one).
  4. Click "Take Snapshot".
  5. Wait a bit (coffee is a good option).
  6. When the save button appears on the left side of the panel, click it to save the
    profile locally.
  7. Compress the file (gzip or regular zip) to make the file smaller.
  8. Send the compressed file to whoever asked for it (if you trust them).

While the profile is in progress, the tab might be frozen or unresponsive.


Monorepo (`docs/monorepo.md`)

Monorepo

Some words about the structure of monorepo we are using here.

Structure

The monorepo is focused around multiple Typescript projects coming together to form an Element Web & Element Desktop app.
Some of the underlying typescript projects are useful for re-use elsewhere,
e.g. @element-hq/web-shared-components is reused by https://github.com/element-hq/aurora.

  • apps - this directory holds the apps we build, element-web & element-desktop
    • Things in here are not published to npm
    • Things in here have very non-standard publishing steps, e.g. Element Desktop .deb ships via reprepro.
    • Things in here are in lock-step versions with each other
    • Things in here are represented as a group in Immutable Github Releases
    • Things in here support pre-releases & hotfixes
  • packages - this directory holds some npm packages we maintain in order to build the apps
    • Things in here are published to npm
    • Things in here respect SemVer
    • Things in here are independently versioned
    • Things in here have a very simple publishing stage of pnpm publish
    • Things in here do not support pre-releases & hotfixes
  • modules - this directory will hold some Element Web/Desktop modules we maintain in order to add environment-specific functionalities atop Element
    • Things in here are not published to npm

Branches

  • develop - this is the default branch and should always be buildable, this is what developers use as a base branch for their pull requests
    • Deployed via CD to develop.element.io
  • #TODO should we just use short-lived release branches? We'd need to effectively interlace them for the various packages which feels messy
  • staging - this branch is used to build the latest/next release.
    • During a normal release cycle, develop is merged into staging to "cut" a release candidate
      • Additional changes such as version bumps & changelogs are committed on top
    • During a hotfix/security release, changes are directly cherry-picked to staging to "cut" a release based on the last release rather than develop
    • When a release is finished, i.e. we've shipped the final release for a given version, we merge staging->develop to maintain continuity
  • backport/* - these branches are used for cherry-picking entire pull requests from develop to staging, either to patch a release candidate, or to perform a hotfix release
  • /* - these feature branches are used for development, and may branch off develop or another feature branch

Tags

  • v* - these tags are used by the releases shown in the Github Releases UI, as in, the overall app release group
  • @* - these tags represent the release state of an individual npm package from the packages/* dir

Ultimately, the treatment of the 3 types of submodules we host in this repository is quite asymmetrical but this is by design,
to simplify processes around projects which do not need the complexities of element-web & element-desktop.


Native Node Modules (`docs/native-node-modules.md`)

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.

Currently the only native module is Seshat,
which adds support for local event indexing and full text search in E2E encrypted rooms.

Prebuilt binaries

Seshat is consumed via the @matrix-org/seshat
npm package, which ships prebuilt binaries for every platform Element Desktop supports as
per-platform optionalDependencies:

Platform Architectures SQLCipher
Linux x64, arm64 static
macOS x64, arm64 static
Windows x64, arm64 static

pnpm only installs the binary matching the machine running the install. Building for
another architecture (for example a Windows arm64 package on an x64 machine, or the macOS
universal package) needs pnpm to install the extra binaries too. This is done by adding a
supportedArchitectures block to
pnpm-workspace.yaml before running pnpm install, for example for a macOS universal build:

yaml
supportedArchitectures:
    os: [current] # Assuming you are on "darwin"
    cpu: [x64, arm64]

The CI workflows do this automatically. The electron-builder configuration prunes binaries
for other platforms and architectures from the packaged app, so only the ones needed by the
target end up in the package.

Verifying a Linux package

The Linux CI workflow checks every .node file in the packaged app with
apps/desktop/scripts/glibc-check.sh to ensure it does not require a newer glibc than
our oldest supported distribution ships. If you upgrade Seshat and this check fails,
the MAX_GLIBC value in .github/workflows/build_desktop_linux.yaml documents the current ceiling.

Building from source

Should you need to build Seshat yourself, for example for an unsupported platform or to
link against the system SQLCipher, follow the instructions in the
Seshat repository
and use pnpm link to substitute the resulting package for @matrix-org/seshat.


Oauth (`docs/oauth.md`)

OAuth2 and delegated authentication

See https://areweoidcyet.com/client-implementation-guide/ for implementation details.

Element Web uses /auth_metadata to discover the configured provider.
Where a valid configuration is discovered, OAuth2 native login flow will be the only login option offered.
Element Web will attempt to dynamically register with the configured OP.
Then, authentication will be completed as described here.

Statically configured OAuth2 clients

Clients that are already registered with the OP can configure their client_id in config.json.
Where static configuration exists for the OP dynamic client registration will not be attempted.

json
{
    "oidc_static_clients": {
        "https://dummyoidcprovider.com/": {
            "client_id": "abc123"
        }
    }
}

Packaging (`docs/packaging.md`)

Packaging nightlies

Element Desktop nightly builds are build automatically by the Github Actions workflow.
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
  2. Feel free to make changes to the checkboxes depending on the circumstances
  3. 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.


Playwright (`docs/playwright.md`)

Playwright in Element Web

Overview

Element Web contains two sets of Playwright tests:

  1. Element Web E2E Tests (playwright/e2e/) - Full end-to-end tests of the Element Web application with real homeserver instances
  2. Shared Components Tests (packages/shared-components/) - Visual regression tests for the shared component library using Storybook

Both test suites run automatically in CI on every pull request and on every merge to develop & master.

Prerequisites

Before running Playwright tests, ensure you have the following set up:

1. Install Playwright Browsers and System Dependencies

Follow the Playwright installation instructions:

sh
pnpm playwright install --with-deps

2. Container Runtime

See Supported Container Runtimes for details on supported container runtimes (Docker, Podman, Colima).

3. Element Web Server (for E2E tests)

Element Web E2E tests require an instance running on http://localhost:8080 (configured in playwright.config.ts).

You can either:

  • Run manually: pnpm start in a separate terminal (not working for screenshot tests running in a docker environment).
  • Auto-start: Playwright will start the webserver automatically if it's not already running

Running the Tests

Element Web E2E Tests

Our main Playwright tests run against a full Element Web instance with Synapse/Dendrite homeservers.

Run all E2E tests:

sh
pnpm run test:playwright

Run a specific test file:

sh
pnpm run test:playwright playwright/e2e/register/register.spec.ts

Run tests interactively with Playwright UI:

sh
pnpm run test:playwright:open

Run screenshot tests only:

[!WARNING]
This command run the playwright tests in a docker environment.

sh
pnpm run test:playwright:screenshots

For more information about visual testing, see Visual Testing.

Additional command line options: https://playwright.dev/docs/test-cli

Shared Components Tests

See the Shared Components README for instructions on running the shared components Playwright tests.

Projects

By default, Playwright runs tests against all "Projects": Chrome, Firefox, "Safari" (Webkit), Dendrite and Picone.

  • Chrome, Firefox, Safari run against Synapse
  • Dendrite and Picone run against Chrome

Misc:

  • Pull Request CI: Tests run only against Chrome
  • Merge Queue: Tests run against all projects
  • Some tests are excluded from certain browsers due to incompatibilities (see Test Tags)

How the Tests Work

Test Structure

Element Web tests are located in the playwright/ subdirectory:

  • playwright/e2e/ - E2E test files
  • playwright/testcontainers/ - Testcontainers for Synapse/Dendrite instances
  • playwright/snapshots/ - Visual regression test screenshots
  • playwright/pages/ - Page object models
  • playwright/plugins/ - Custom Playwright plugins

Homeserver Setup

Homeservers (Synapse or Dendrite) are launched by Playwright workers and reused for all tests matching the worker configuration.

Configure Synapse options:

typescript
test.use({
    synapseConfig: {
        // Configuration options for the Synapse instance
    },
});

Important notes:

  • Homeservers are reused between tests for efficiency
  • Please use unique names for any rooms put into the room directory as they may be visible from other tests, the suggested approach is to use testInfo.testId within the name or lodash's uniqueId.
  • We remove public rooms from the room directory between tests but deleting users doesn't have a homeserver agnostic solution.
  • Homeserver logs are attached to Playwright test reports

Fixtures

We heavily leverage Playwright fixtures to provide:

  • Homeserver instances (homeserver)
  • Logged-in users (user)
  • Bot users (bot)
  • Application state (app)

See Writing Tests for usage examples.

Writing Tests

For general Playwright best practices, see:

Getting a Homeserver

Use the homeserver fixture to acquire a Homeserver instance:

typescript
test("should do something", async ({ homeserver }) => {
    // homeserver is a ready-to-use Synapse/Dendrite instance
});

The fixture provides:

  • Server port information
  • Instance ID for shutdown
  • Registration shared secret (registrationSecret) for registering users via REST API

Homeserver instances are:

  • Reasonably cheap to start (first run may be slow while pulling Docker image)
  • Automatically cleaned up by the fixture

Logging In

Use the user fixture to get a logged-in user:

typescript
test("should do something", async ({ user }) => {
    // user is logged in and ready to use
});

Customize the user:

typescript
test.use({
    displayName: "Alice",
});

test("should do something", async ({ user }) => {
    // user is logged in as "Alice"
});

What the fixture does:

  • Registers a random userId with the registrationSecret
  • Generates a random password (or uses specified display name)
  • Seeds localStorage with credentials
  • Loads the app at path /
  • Provides user details for User-Interactive Auth if needed

Joining a Room

To start with a user in a room:

typescript
test("should send a message", async ({ user, app, bot }) => {
    // Use the bot client to create a room
    const roomId = await bot.createRoom({
        name: "Test Room",
        invite: [user.userId],
    });

    // Accept the invite using the app client
    await app.client.joinRoom(roomId);

    // Now ready to test messaging
});

Best practice: Use the REST API (via bot or app.client) to set up room state rather than driving the UI.

Using matrix-js-sdk

Due to CI constraints, use the matrix-js-sdk module exposed on window.matrixcs:

typescript
const matrixcs = window.matrixcs;

Limitation: Only accessible when the app is loaded. This may be revisited in the future.

Best Practices

For more guidance, see the Playwright best practices guide.

1. Test from the User's Perspective

Work with roles, labels, and accessible elements rather than CSS selectors:

typescript
// Good
await page.getByRole("button", { name: "Send" }).click();

// Avoid
await page.locator(".mx_MessageComposer_sendButton").click();

See https://playwright.dev/docs/locators for more guidance.

2. Test Well-Isolated Functionality

  • Focus on specific, well-defined units of functionality
  • Easier to debug when tests fail
  • More maintainable over time

3. Maintain Test Independence

  • Each test should run successfully in isolation
  • Don't depend on state from other tests
  • Clean up after your test if needed

4. Minimize UI Driving for Setup

  • Use REST APIs to set up test state when possible
  • Only drive the UI for the functionality you're actually testing

Example:

typescript
// Testing reactions - good approach
test("should react to a message", async ({ page, app, bot }) => {
    // Send message via API
    const eventId = await bot.sendMessage(roomId, "Hello");

    // Test the reaction UI
    await page.getByText("Hello").hover();
    await page.getByRole("button", { name: "React" }).click();
    await page.getByLabel("😀").click();

    // Verify reaction was sent
    await expect(page.getByLabel("😀 1")).toBeVisible();
});

5. Avoid Explicit Waits

Playwright locators and assertions automatically wait and retry:

typescript
// Good - implicit waiting
await expect(page.getByText("Message sent")).toBeVisible();

// Avoid - explicit waits
await page.waitForTimeout(1000);

For dynamic content:

typescript
// Assert on the final state - Playwright will wait for it
await expect(page.getByRole("textbox")).toHaveValue("Edited message");
await expect(page.getByText("edited")).toBeVisible();

When you do need to wait:

typescript
// Wait for network requests
await page.waitForResponse("**/messages");

// Wait for specific conditions
await page.waitForFunction(() => window.matrixcs !== undefined);

Visual Testing

Playwright has built-in support for visual comparison testing.

Screenshot location: playwright/snapshots/

Rendering environment: Linux Docker (for consistency across environments)

Test Tag for Screenshots

All screenshot tests must use the @screenshot tag:

typescript
test("should render message list", { tag: "@screenshot" }, async ({ page }) => {
    await expect(page).toMatchScreenshot("message-list.png");
});

Purpose of @screenshot tag:

  • Allows running only screenshot tests via test:playwright:screenshots
  • Speeds up screenshot test runs and updates

Taking Screenshots

Use the custom toMatchScreenshot assertion (not the native toHaveScreenshot):

typescript
await expect(page).toMatchScreenshot("my-screenshot.png");

Why a custom assertion? We inject custom CSS to stabilize dynamic UI elements (e.g., BaseAvatar color selection based on Matrix ID hash).

Masking Dynamic Content

Always mask dynamic content that changes between runs:

typescript
await expect(page).toMatchScreenshot("chat.png", {
    mask: [page.locator(".mx_MessageTimestamp"), page.locator(".mx_BaseAvatar")],
});

Common elements to mask:

  • Timestamps
  • Avatars (when dynamic)
  • Animated elements
  • User-generated IDs

See Playwright masking docs for more details.

Updating Screenshots

This command runs only tests tagged with @screenshot in the Docker environment.
When you need to update screenshot baselines (e.g., after intentional UI changes):

sh
pnpm run test:playwright:screenshots

Important: Always use this command to update screenshots rather than running tests locally with --update-snapshots.

Why? Screenshots must be rendered in a consistent Linux Docker environment because:

  • Font rendering differs between operating systems (macOS, Windows, Linux)
  • Subpixel rendering varies across systems
  • Browser rendering engines have platform-specific differences

Using test:playwright:screenshots ensures screenshots are generated in the same Docker environment used in CI, preventing false failures due to rendering differences.

Test Tags

Test tags categorize tests for efficient subset execution.

Available Tags

  • @mergequeue: Slow or flaky tests covering rarely-updated app areas

    • Not run on every PR commit
    • Run in the Merge Queue
  • @screenshot: Tests using toMatchScreenshot for visual regression testing

  • @no-firefox: Tests unsupported in Firefox

    • Automatically skipped in Firefox project
    • Common reason: Service worker required (disabled in Playwright Firefox for routing)
  • @no-webkit: Tests unsupported in Webkit

    • Automatically skipped in Webkit project
    • Common reasons: Service worker required, microphone functionality unavailable

Running All Tests in a PR

Add the X-Run-All-Tests label to your pull request to run all tests, including @mergequeue tests.

Supported Container Runtimes

We use testcontainers to manage Synapse, Matrix Authentication Service, and other service instances.

Supported runtimes:

Platform-Specific Configuration

Colima users:

If using Colima, you may need to set the TMPDIR environment variable to allow bind mounting temporary directories:

sh
export TMPDIR=/tmp/colima
# or
export TMPDIR=$HOME/tmp

Pr Previews (`docs/pr-previews.md`)

Pull Request Previews

Pull requests to the React SDK layer (and in the future other layers as well)
automatically set up a preview site with a full deployment of Element with the
changes from the pull request added in so that anyone can easily test and review
them. This is especially useful for checking visual and interactive changes.

To access the preview site, click the link in the description of the PR.

The checks section could be collapsed at first, so you may need to click "Show
all checks" to reveal them. Look for an entry that mentions deploy-preview. It
may be at the end of the list, so you may need scroll a bit to see it. To access
the preview site, click the "Details" link in the deploy preview row.

Important: Please always use test accounts when logging into preview sites,
as they may contain unreviewed and potentially dangerous code that could damage
your account, exfiltrate encryption keys, etc.

FAQs

Are preview sites created for pull requests from contributors?

Yes, they are created for all PRs from any author.

Do preview sites expire after some time period?

No, there is no expiry date, so they should remain accessible indefinitely, but
of course they obviously aren't meant to live beyond the development workflow,
so please don't rely on them for anything important. They may disappear at any
time without notice.


Release (`docs/release.md`)

Tip: Paste this into the browser console to make the checkboxes on this page tickable. (Bear in mind that your ticks will be lost if you reload though.)

text
document.querySelectorAll("input[type='checkbox']").forEach(i => {i.disabled = false;})

Branches

develop

The develop branch holds the very latest and greatest code we have to offer, as such it may be less stable.
It is auto-deployed on every commit to element-web or matrix-js-sdk to develop.element.io via GitHub Actions build_develop.yml.

staging

The staging branch corresponds to the very latest release regardless of whether it is an RC or not. Deployed to staging.element.io manually.
It is auto-deployed on every release of element-web to staging.element.io via GitHub Actions deploy.yml.

master

The master branch is the most stable as it is the very latest non-RC release. Deployed to app.element.io manually.

Versions

The matrix-js-sdk follows semver, most releases will bump the minor version number.
Breaking changes will bump the major version number.
Element Web & Element Desktop do not follow semver and always have matching version numbers. The patch version number is normally incremented for every release.

Release Types

Release candidate

A normal release begins with a Release Candidate on the Tick phase of the release cycle,
and may contain as many further RCs as are needed before the Tock phase of cycle.
Each subsequent RC may add additional commits via any of the means of preparation.

A normal release is the most typical run-of-the-mill release,
with at least one RC (Release Candidate) followed by a FINAL release.
The typical cadence for these is every 2 weeks we'll do a new initial RC,
then the following week we'll do that release cycle's FINAL release with sometimes more RCs in between, as needed.

Final

A normal release culminates with a Final release on the Tock phase of the cycle.
This may be merely shipping the very latest RC with an adjusted version number,
but can also include (hopefully small) additional changes present on staging if they are deemed safe to skip an RC.

Hotfix / Security

This is an accelerated type of release which sits somewhere between RC and Final.
They tend to contain few patches delta from the previous release but also skip any form of RC
and in the case of Security the patch lands on GitHub only moments prior.
For all intents and purposes they are the same as a Final release but with a different purpose.

Release Blockers

You should become release rabbit on the day after the last full release.
For that week, it's your job to keep an eye on the Releases room and see whether any issues marked X-Release-Blocker are opened,
or were already open. You should chase people to fix them, so that on RC day you can make the release.

If release-blocking issues are still open, you need to delay the release until they are fixed or reclassified.

There are two labels for tracking release blockers.

X-Release-Blocker

This label applied to an issue means we cannot ship a release affected by the specific issue.
This means we cannot cut branches for an RC but security & hotfix releases may still be fine.

X-Upcoming-Release-Blocker

This label applied to an issue means that the next (read: not current) release cycle will be affected by the specific issue.
This label will automagically convert to X-Release-Blocker at the conclusion of a full release.

Repositories

This release process revolves around our main repositories:

We own other repositories, but they have more ad-hoc releases and are not part of the bi-weekly cycle:

Prerequisites

  • You must be part of the 2 Releasers GitHub groups:
  • You will need access to the VPN (docs) to be able to follow the instructions under Deploy below.
  • You will need the ability to SSH in to the production machines to be able to follow the instructions under Deploy below. Ensure that your SSH key has a non-empty passphrase, and you registered your SSH key with Ops. Log a ticket at https://github.com/matrix-org/matrix-ansible-private and ask for:
    • Two-factor authentication to be set up on your SSH key. (This is needed to get access to production).
    • SSH access to horme (staging.element.io and app.element.io)
    • Permission to sudo on horme as the user element
  • You need "jumphost" configuration in your local ~/.ssh/config. This should have been set up as part of your onboarding.

Overview

mermaid
flowchart TD
    P[[Prepare staging branches]]
    P --> R1

    subgraph Releasing
        R1[[Releasing matrix-js-sdk]]
        R2[[Releasing element-web]]

        R1 --> R2 --> R3
    end

    R3 --> D1

    subgraph Deploying
        D1[\Deploy staging.element.io/]
        D2[\Check docker build/]
        D3[\Deploy app.element.io/]
        D4[\Check desktop package/]

        D1 --> D2 --> D
        D{FINAL?}
        D -->|Yes| D3 --> D4
    end

    D -->|No| H1
    D4 --> H1

    subgraph Housekeeping
        H1[\Update topics/]
        H2[\Announce/]
        H3[\Archive done column/]
        H4[\Add diary entry/]
        H5[\Renovate/]

        H1 --> H2 --> H

        H{FINAL?}
        H -->|Yes| H3 --> H4 --> DONE
        H -->|No| H5
    end

    DONE([You are done!])
    H5 --> DONE

Preparation

The goal of this stage is to get the code you want to ship onto the staging branch.
There are multiple ways to accomplish this depending on the type of release you need to perform.

For the first RC in a given release cycle the easiest way to prepare branches is using the
Cut branches automation -
this will take develop and merge it into the staging on the chosen repositories.

For subsequent RCs, if you need to include a change you may PR it directly to the staging branch or rely on the
backport automation via labelling a PR to develop with backport staging which will cause a new PR to be opened
which backports the requested change to the staging branch.

For security, you may wish to merge the security advisory private fork or apply the patches manually and then push them directly to staging.
It is worth noting that at the end of the Final/Hotfix/Security release staging is merged to master which is merged back into develop -
this means that any commit which goes to staging will eventually make its way back to the default branch.

  • The staging branch is prepared

Releasing

Shortly after concluding the preparation stage (or pushing any changes to staging in general);
a draft release will be automatically made on the 4 project repositories with suggested changelogs and version numbers.

Note: we should add a step here to write summaries atop the changelogs manually, or via AI

Publishing the SDKs to npm also commits a dependency upgrade to the relevant downstream projects,
if you skip a layer of this release (e.g. for a hotfix) then the dependency will remain on #develop which will be
switched back to the version of the dependency from the master branch to not leak develop code into a release.

Matrix JS SDK

  • Check the draft release which has been generated by the automation
  • Make any changes to the release notes in the draft release as are necessary - Do not click publish, only save draft
  • Kick off a release using the automation - making sure to select the right type of release. For anything other than an RC: choose final. You should not need to ever switch off either of the Publishing options.

Element Web

  • Check the draft release which has been generated by the automation
  • Make any changes to the release notes in the draft release as are necessary - Do not click publish, only save draft
  • Kick off a release using the automation - making sure to select the right type of release. For anything other than an RC: choose final. You should not need to ever switch off either of the Publishing options.

Deploying

We ship the SDKs to npm, this happens as part of the release process.
We ship Element Web to dockerhub, ghcr.io, *.element.io, and packages.element.io.
We ship Element Desktop to packages.element.io.

  • Check that element-web has shipped to dockerhub & ghcr.io
  • Check that the staging deployment has completed successfully
  • Test staging.element.io

For final releases additionally do these steps:

  • Deploy app.element.io. See docs.
  • Test app.element.io
  • Ensure Element Web package has shipped to packages.element.io
  • Ensure Element Desktop packages have shipped to packages.element.io

If you need to roll back a deployment to staging.element.io,
you can run the deploy.yml automation choosing an older tag which you wish to deploy.

Housekeeping

We have some manual housekeeping to do in order to prepare for the next release.

(show)

With wording like:

Element Web v1.11.24 is here!

This version adds ... and fixes bugs ...

Check it out at app.element.io, in Element Desktop, or from Docker Hub. Changelog and more details at https://github.com/element-hq/element-web/releases/tag/v1.11.24

For the first RC of a given release cycle do these steps:

For final releases additionally do these steps:

  • Archive done column on the team board Note: this should be automated
  • Add entry to the milestones diary. The document says only to add significant releases, but we add all of them just in case.

Review (`docs/review.md`)

Review Guidelines

The following summarises review guidelines that we follow for pull requests in
Element Web and other supporting repos. These are just guidelines (not strict
rules) and may be updated over time.

Code Review

When reviewing code, here are some things we look for and also things we avoid:

We review for

  • Correctness
  • Performance
  • Accessibility
  • Security
  • Quality via automated and manual testing
  • Comments and documentation where needed
  • Sharing knowledge of different areas among the team
  • Ensuring it's something we're comfortable maintaining for the long term
  • Progress indicators and local echo where appropriate with network activity

We should avoid

  • Style nits that are already handled by the linter
  • Dramatically increasing scope

Good practices

  • Use empathetic language
  • Authors should prefer smaller commits for easier reviewing and bisection
  • Reviewers should be explicit about required versus optional changes
    • Reviews are conversations and the PR author should feel comfortable
      discussing and pushing back on changes before making them
  • Reviewers are encouraged to ask for tests where they believe it is reasonable
  • Core team should lead by example through their tone and language
  • Take the time to thank and point out good code changes
  • Using softer language like "please" and "what do you think?" goes a long way
    towards making others feel like colleagues working towards a common goal

Workflow

  • Authors should request review from the element-web team by default (if someone on
    the team is clearly the expert in an area, a direct review request to them may
    be more appropriate)
  • Reviewers should remove the team review request and request review from
    themselves when starting a review to avoid double review
  • If there are multiple related PRs authors should reference each of the PRs in
    the others before requesting review. Reviewers might start reviewing from
    different places and could miss other required PRs.
  • Avoid force pushing to a PR after the first round of review
  • Use the GitHub default of merge commits when landing (avoid alternate options
    like squash or rebase)
  • PR author merges after review (assuming they have write access)
  • Assign issues only when in progress to indicate to others what can be picked
    up

Code Quality

In the past, we have occasionally written different kinds of tests for
Element and the SDKs, but it hasn't been a consistent focus. Going forward, we'd
like to change that.

  • For new features, code reviewers will expect some form of automated testing to
    be included by default
  • For bug fixes, regression tests are of course great to have, but we don't want
    to block fixes on this, so we won't require them at this time

The above policy is not a strict rule, but instead it's meant to be a
conversation between the author and reviewer. As an author, try to think about
writing a test when making your next change. As a reviewer, try to think about
how you might test the area of code you are reviewing. If the reviewer agrees
it would be quite difficult to test some new feature, then it's okay for them to
accept the change without tests for now, but we'd eventually like to be more
strict about this further down the road.

If you do spot areas that are quite hard to test today, please let us know in
#element-dev:matrix.org. We can
work on improving the app architecture and testing helpers so that future tests
are easier for everyone to write, but we won't know which parts are difficult
unless people shout when stumbling through them.

We recognise that this testing policy will slow things down a bit, but overall
it should encourage better long-term health of the app and give everyone more
confidence when making changes as coverage increases over time.

For changes guarded by a feature flag, we currently lean towards prioritising
our ability to evolve quickly using such flags and thus we will not currently
require tests to appear at the same time as the initial landing of features
guarded by flags, as long as (for new flagged features going forward) the
feature author understands that they are effectively deferring part of their
work (adding tests) until later and tests are expected to appear before the
feature can be enabled by default.

Design and Product Review

We want to ensure that all changes to Element fit with our design and product
vision. We often request review from those teams so they can provide their
perspective.

In more detail, our usual process for changes that affect the UI or alter user
functionality is:

  • For changes that will go live when merged, always flag Design and Product
    teams as appropriate
  • For changes guarded by a feature flag, Design and Product review is not
    required (though may still be useful) since we can continue tweaking

As it can be difficult to review design work from looking at just the changed
files in a PR, a preview site that includes your changes
will be added automatically so that anyone who's interested can try them out
easily.

Before starting work on a feature, it's best to ensure your plan aligns well
with our vision for Element. Please chat with the team in
#element-dev:matrix.org before
you start so we can ensure it's something we'd be willing to merge.


Room List (`docs/room-list.md`)

Room list

The room list is the sorted, filtered list of rooms in the left-hand navigation panel, always
scoped to the active space. It is a full MVVM feature split across three layers:

  • Model — RoomListStoreV3, the store that keeps every room sorted and answers queries for
    the rooms in the active space. It lives in
    apps/web/src/stores/room-list-v3/.
  • View models — adapt the store (and other stores) into snapshots for the UI. They live in
    apps/web/src/viewmodels/room-list/.
  • Views — the presentational React components, owned by @element-hq/web-shared-components.

Architecture

mermaid
flowchart TD
    events["Matrix events"] --> store
    otherStores["Notification / preview / call stores, room events"] --> rlvm
    otherStores --> itemVM
    otherStores --> sectionHeaderVM

    subgraph model["Model"]
        store["RoomListStoreV3(owns the skip list)"]
    end

    subgraph vms["View models"]
        rlvm["RoomListViewModel"]
        itemVM["RoomListItemViewModel"]
        sectionHeaderVM["RoomListSectionHeaderViewModel"]
        headerVM["RoomListHeaderViewModel"]
        searchVM["RoomListSearchViewModel"]
    end

    subgraph views["Views (Shared components)"]
        rlview["RoomListView"]
        virtualizedView["VirtualizedRoomListView"]
        itemView["RoomListItemView"]
        sectionHeaderView["RoomListSectionHeaderView"]
        headerView["RoomListHeaderView"]
        searchView["RoomListSearchView"]
    end

    rlvm -->|"consume events"| store
    rlvm -->|"creates"| itemVM
    rlvm -->|"creates"| sectionHeaderVM
    rlview -->|"snapshot"| rlvm
    rlview -->|"renders"| virtualizedView
    virtualizedView -->|"renders"| itemView
    virtualizedView -->|"renders"| sectionHeaderView
    virtualizedView -->|"snapshot"| rlvm
    itemView -->|"snapshot"| itemVM
    sectionHeaderView -->|"snapshot"| sectionHeaderVM
    headerView -->|"snapshot"| headerVM
    searchView -->|"snapshot"| searchVM

Model — the store

RoomListStoreV3 (the "V3" is the third implementation) is a singleton exposed as
RoomListStoreV3.instance. Unlike the previous implementations, which re-computed lists on
demand, V3 keeps every room permanently sorted so retrieval is cheap.

The skip list. The core data structure is a
skip list: stacked linked lists that keep every room
permanently sorted, so a room that changes is simply re-inserted into place and the rest of the
list is untouched. Rooms are wrapped in RoomNodes that cache whether the room is in the active
space and which filters it matches, so reading the list is just an ordered walk that drops the
nodes outside the space or not matching the requested filters.

Sorters. A sorter defines the order of the list. There are three: Alphabetic (by room
name), Recency (most recent meaningful activity, with low-priority and muted rooms forced to
the bottom), and Unread (by unread importance). The user's choice is persisted and can be
changed at runtime, which rebuilds the list.

Filters. A filter answers a single yes/no question about a room, and each room's matching
filters are precomputed on its node. Filters serve two roles: capability filters back the
primary filter chips in the UI (Unread, People, Rooms, Favourites, Mentions, Invites, Low
Priority), and section-tag filters decide which section a room belongs to. Not all of the
capability filters are offered as chips at all times: while sectioning is enabled, Favourites and
Low Priority are hidden, since those rooms already have their own sections.

Sections. The store groups rooms into named sections (Favourites, Low Priority, Chats, and
user-created custom sections) using the section-tag filters described above. Sections are a topic
of their own — see Sections below.

Spaces and updates. The list is always scoped to the active space; rather than re-filter on
every read, each node caches its active-space membership and the store recomputes that flag when
the space changes. The store listens for the Matrix events that affect ordering or membership
(receipts, tag changes, account data, push rules, decryption, timeline events, membership) and
responds by re-inserting or removing the single affected room. Emissions to consumers are
coalesced with requestAnimationFrame, so a burst of updates within a frame collapses into one
notification.

Public surface. This is the seam the view models bind to:

  • Events: ListsUpdate (lists changed), ListsLoaded (initial load done), SectionCreated,
    and RoomTagged (a locally-initiated tag change, which drives the "chat moved" toast).
  • getSortedRoomsInActiveSpace(filterKeys?) returns the sorted, filtered rooms grouped into
    sections. Narrower helpers exist too (DM rooms, server-notice rooms, the full sorted list).
  • Section mutators (createSection / editSection / removeSection / reorderSection) and
    resort.

Note that sticky-room behaviour lives in the view model, not the store — the store itself is
unaware of a selected room.

Sections

Sections are the named groups the room list displays. Membership is driven entirely by the Matrix
m.tag account data on each room, so moving a room between sections is just a matter of changing
its tags:

  • Favourites and Low Priority use the default m.favourite and m.lowpriority tags and
    are pinned to the top and bottom of the list respectively.
  • Chats is a synthetic catch-all section (tag chats) for every room that isn't in any other
    explicit section.
  • Custom sections are user-created. Each is identified by a generated tag of the form
    element.io.section., and a room is placed in it by tagging the room with that tag.

The store keeps an ordered list of section tags — Favourites first, Low Priority last, and the
custom sections plus Chats reorderable in between (new custom sections are inserted just above
Chats by default). Custom sections can be created, renamed, removed, and reordered through
dialogs; that logic lives in section.ts.

Each custom section also records the space it was created in, which controls the visibility of
empty sections: an empty custom section is only shown in the space it belongs to, so sections
created in one space don't clutter unrelated spaces. Legacy sections without a stored space (or
whose space no longer exists) fall back to the Home meta-space. Note that this visibility rule is
applied by RoomListViewModel when it builds its snapshot, not by the store.

Flat list mode

When sectioning is turned off, the room list becomes a single flat list instead of a grouped one.
This is triggered in two places:

  • If the RoomList.showSections setting is disabled, the store skips sectioning altogether and
    getSortedRoomsInActiveSpace() returns a single chats section containing every room in the
    active space.
  • Even with sectioning enabled, RoomListViewModel discards the sections it shouldn't render (the
    empty ones, and custom sections belonging to another space) and treats what remains as flat
    (isFlatList) if it is nothing at all, or the Chats catch-all on its own — for example when the
    user has no favourite, low-priority, or custom-tagged rooms.

In flat mode the view renders a FlatVirtualizedList (no section headers); otherwise it renders a
GroupedVirtualizedList with headers and section drag-and-drop.

Settings

Sections are configured entirely through settings:

  • RoomList.showSections — whether sectioning is enabled at all. When off, the list is flat
    (see above).
  • RoomList.CustomSectionData (account level) — the custom-section definitions, keyed by tag.
    Each entry stores the tag, the user-chosen name, and the space the section was created in.
    Malformed entries are dropped when the data is read.
  • RoomList.OrderedCustomSections (account level) — the display order of the reorderable
    sections (the custom sections and Chats). Favourites and Low Priority are not stored here since
    they are always pinned to the top and bottom.
  • RoomList.SectionExpansionState (device level) — the expanded/collapsed state of each
    section, stored per space and then per section tag. Sections default to expanded when no state
    has been persisted.

The account-level settings sync across a user's devices, while the expansion state is
device-local so that collapsing a section on one device doesn't affect the others.

View models

The view models in apps/web/src/viewmodels/room-list/
extend BaseViewModel and produce immutable snapshots consumed by the views (see MVVM
for the base pattern).

RoomListViewModel is the root orchestrator and the only view model that subscribes to
the store's list events and calls getSortedRoomsInActiveSpace(). It builds the top-level
snapshot — whose sections carry only room IDs, not room objects — and owns the sticky-room
logic, the active filter, the toasts, section drag-and-drop, and keyboard navigation. It also
lazily creates and owns the child view models.

RoomListItemViewModel (one per room) and RoomListSectionHeaderViewModel (one per
section) are created on demand by the root view model. Crucially, they do not listen to the
store's list events; instead they subscribe to fine-grained domain stores directly —
notification state, message previews, calls, room events and settings — so a single row can
update independently of the rest of the list. The section header view model draws on a narrower
set of those, and is fed its set of rooms imperatively by the parent so it can aggregate their
notification state.

RoomListHeaderViewModel (the header bar: space title, sort menu, create actions) and
RoomListSearchViewModel (the search/dial/explore row) are decoupled siblings of the root
view model. They do not share state directly; the header view model and the root view model talk
through the global dispatcher, in both directions — collapse-all-sections, for instance, is
requested by the header and the resulting state dispatched back to it.

Permission and create-room helpers used by these view models live in
utils.ts.

Views

The presentational components are owned by @element-hq/web-shared-components (developed in
Storybook); apps/web supplies the view models, a renderAvatar callback and a key handler for
landmark navigation, and the shared package owns the rendering. The app-side entry point is
RoomListPanel, which
composes the search row, the header view, and the room list itself.

The room list proper is RoomListView, which renders the filter chips and any toast above a body
that is a loading skeleton, an empty state, or — in the usual case — VirtualizedRoomListView
(built on react-virtuoso). Virtualization drives the lazy lifecycle of
the child view models: as rows scroll into view the list calls back through
getRoomItemViewModel(id) and getSectionHeaderViewModel(tag) to obtain the view model for each
rendered room or header, and reports its visible range so off-screen item view models can be
disposed. Because each row binds to its own view model, it re-renders on its own data without
re-rendering the whole list.

The list renders either as a flat list or a grouped list with section headers, depending on the
isFlatList flag in the snapshot (see Flat list mode); in the grouped case,
drag-and-drop is wired back to the root view model, which reorders sections, moves rooms between
them, and collapses the sections for the duration of a section drag.


Scrolling (`docs/scrolling.md`)

ScrollPanel

Updates

During an onscroll event, we check whether we're getting close to the top or bottom edge of the loaded content. If close enough, we fire a request to load more through the callback passed in the onFillRequest prop. This returns a promise is passed down from TimelinePanel, where it will call paginate on the TimelineWindow and once the events are received back, update its state with the new events. This update trickles down to the MessagePanel, which rerenders all tiles and passed that to ScrollPanel. ScrollPanels componentDidUpdate method gets called, and we do the scroll housekeeping there (read below). Once the rerender has completed, the setState callback is called and we resolve the promise returned by onFillRequest. Now we check the DOM to see if we need more fill requests.

Prevent Shrinking

ScrollPanel supports a mode to prevent it shrinking. This is used to prevent a jump when at the bottom of the timeline and people start and stop typing. It gets cleared automatically when 200px above the bottom of the timeline.

BACAT (Bottom-Aligned, Clipped-At-Top) scrolling

BACAT scrolling implements a different way of restoring the scroll position in the timeline while tiles out of view are changing height or tiles are being added or removed. It was added in https://github.com/matrix-org/matrix-react-sdk/pull/2842.

The motivation for the changes is having noticed that setting scrollTop while scrolling tends to not work well, with it interrupting ongoing scrolling and also querying scrollTop reporting outdated values and consecutive scroll adjustments cancelling each out previous ones. This seems to be worse on macOS than other platforms, presumably because of a higher resolution in scroll events there. Also see https://github.com/vector-im/element-web/issues/528. The BACAT approach allows to only have to change the scroll offset when adding or removing tiles.

The approach taken instead is to vertically align the timeline tiles to the bottom of the scroll container (using flexbox) and give the timeline inside the scroll container an explicit height, initially set to a multiple of the PAGE_SIZE (400px at time of writing) as needed by the content. When scrolled up, we can compensate for anything that grew below the viewport by changing the height of the timeline to maintain what's currently visible in the viewport without adjusting the scrollTop and hence without jumping.

For anything above the viewport growing or shrinking, we don't need to do anything as the timeline is bottom-aligned. We do need to update the height manually to keep all content visible as more is loaded. To maintain scroll position after the portion above the viewport changes height, we need to set the scrollTop, as we cannot balance it out with more height changes. We do this 100ms after the user has stopped scrolling, so setting scrollTop has not nasty side-effects.

As of https://github.com/matrix-org/matrix-react-sdk/pull/4166, we are scrolling to compensate for height changes by calling scrollBy(0, x) rather than reading and than setting scrollTop, as reading scrollTop can (again, especially on macOS) easily return values that are out of sync with what is on the screen, probably because scrolling can be done off the main thread in some circumstances. This seems to further prevent jumps.

How does it work?

componentDidUpdate is called when a tile in the timeline is updated (as we rerender the whole timeline) or tiles are added or removed (see Updates section before). From here, checkScroll is called, which calls restoreSavedScrollState. Now, we increase the timeline height if something below the viewport grew by adjusting this.bottomGrowth. bottomGrowth is the height added to the timeline (on top of the height from the number of pages calculated at the last updateHeight run) to compensate for growth below the viewport. This is cleared during the next run of updateHeight. Remember that the tiles in the timeline are aligned to the bottom.

From restoreSavedScrollState we also call updateHeight which waits until the user stops scrolling for 100ms and then recalculates the amount of pages of 400px the timeline should be sized to, to be able to show all of its (newly added) content. We have to adjust the scroll offset (which is why we wait until scrolling has stopped) now because the space above the viewport has likely changed.


Settings (`docs/settings.md`)

Settings Reference

This document serves as developer documentation for using "Granular Settings". Granular Settings allow users to specify
different values for a setting at particular levels of interest. For example, a user may say that in a particular room
they want URL previews off, but in all other rooms they want them enabled. The SettingsStore helps mask the complexity
of dealing with the different levels and exposes easy to use getters and setters.

Levels

Granular Settings rely on a series of known levels in order to use the correct value for the scenario. These levels, in
order of priority, are:

  • device - The current user's device
  • room-device - The current user's device, but only when in a specific room
  • room-account - The current user's account, but only when in a specific room
  • account - The current user's account
  • room - A specific room (setting for all members of the room)
  • config - Values are defined by the setting_defaults key (usually) in config.json
  • default - The hardcoded default for the settings

Individual settings may control which levels are appropriate for them as part of the defaults. This is often to ensure
that room administrators cannot force account-only settings upon participants.

Settings

Settings are the different options a user may set or experience in the application. These are pre-defined in
src/settings/Settings.tsx under the SETTINGS constant, and match the ISetting interface as defined there.

Settings that support the config level can be set in the config file under the setting_defaults key (note that some
settings, like the "theme" setting, are special cased in the config file):

json5
{
  ...
  "setting_defaults": {
    "settingName": true
  },
  ...
}

Getting values for a setting

After importing SettingsStore, simply make a call to SettingsStore.getValue. The roomId parameter should always
be supplied where possible, even if the setting does not have a per-room level value. This is to ensure that the value
returned is best represented in the room, particularly if the setting ever gets a per-room level in the future.

In settings pages it is often desired to have the value at a particular level instead of getting the calculated value.
Call SettingsStore.getValueAt to get the value of a setting at a particular level, and optionally make it explicitly
at that level. By default getValueAt will traverse the tree starting at the provided level; making it explicit means
it will not go beyond the provided level. When using getValueAt, please be sure to use SettingLevel to represent the
target level.

Setting values for a setting

Values are defined at particular levels and should be done in a safe manner. There are two checks to perform to ensure a
clean save: is the level supported and can the user actually set the value. In most cases, neither should be an issue
although there are circumstances where this changes. An example of a safe call is:

javascript
const isSupported = SettingsStore.isLevelSupported(SettingLevel.ROOM);
if (isSupported) {
    const canSetValue = SettingsStore.canSetValue("mySetting", "!curbf:matrix.org", SettingLevel.ROOM);
    if (canSetValue) {
        SettingsStore.setValue("mySetting", "!curbf:matrix.org", SettingLevel.ROOM, newValue);
    }
}

These checks may also be performed in different areas of the application to avoid the verbose example above. For
instance, the component which allows changing the setting may be hidden conditionally on the above conditions.

`SettingsFlag` component

Where possible, the SettingsFlag component should be used to set simple "flip-a-bit" (true/false) settings. The
SettingsFlag also supports simple radio button options, such as the theme the user would like to use.

tsx
<SettingsFlag name="theSettingId" level={SettingsLevel.ROOM} roomId="!curbf:matrix.org"
    label={_td("Your label here")} // optional, if falsey then the `SettingsStore` will be used
    onChange={function(newValue) { }} // optional, called after saving
    isExplicit={false} // this is passed along to `SettingsStore.getValueAt`, defaulting to false
    manualSave={false} // if true, saving is delayed. You will need to call .save() on this component

    // Options for radio buttons
    group="your-radio-group" // this enables radio button support
    value="yourValueHere" // the value for this particular option
/>

Getting the display name for a setting

Simply call SettingsStore.getDisplayName. The appropriate display name will be returned and automatically translated
for you. If a display name cannot be found, it will return null.

Features

Feature flags are just like regular settings with some underlying semantics for how they are meant to be used. Usually
a feature flag is used when a portion of the application is under development or not ready for full release yet, such
as new functionality or experimental ideas. In these cases, the feature name should be named with the feature_*
convention and must be tagged with isFeature: true in the setting definition. By doing so, the feature will automatically
appear in the "labs" section of the user's settings.

Features can be controlled at the config level using the following structure:

json
"features": {
  "feature_lazyloading": true
}

When true, the user will see the feature as enabled. Similarly, when false the user will see the feature as disabled.
The user will only be able to change/see these states if show_labs_settings: true is in the config.

Determining if a feature is enabled

Call SettingsStore.getValue() as you would for any other setting.

Enabling a feature

Call SettingsStore.setValue("feature_name", null, SettingLevel.DEVICE, true).

A note on UI features

UI features are a different concept to plain features. Instead of being representative of unstable or
unpredicatable behaviour, they are logical chunks of UI which can be disabled by deployments for ease
of understanding with users. They are simply represented as boring settings with a convention of being
named as UIFeature.$location where $location is a rough descriptor of what is toggled, such as
URLPreviews or Communities.

UI features also tend to have their own setting controller (see below) to manipulate settings which might
be affected by the UI feature being disabled. For example, if URL previews are disabled as a UI feature
then the URL preview options will use the UIFeatureController to ensure they remain disabled while the
UI feature is disabled.

Setting controllers

Settings may have environmental factors that affect their value or need additional code to be called when they are
modified. A setting controller is able to override the calculated value for a setting and react to changes in that
setting. Controllers are not a replacement for the level handlers and should only be used to ensure the environment is
kept up to date with the setting where it is otherwise not possible. An example of this is the notification settings:
they can only be considered enabled if the platform supports notifications, and enabling notifications requires
additional steps to actually enable notifications.

For more information, see src/settings/controllers/SettingController.ts.

Local echo

SettingsStore will perform local echo on all settings to ensure that immediately getting values does not cause a
split-brain scenario. As mentioned in the "Setting values for a setting" section, the appropriate checks should be done
to ensure that the user is allowed to set the value. The local echo system assumes that the user has permission and that
the request will go through successfully. The local echo only takes effect until the request to save a setting has
completed (either successfully or otherwise).

javascript
SettingsStore.setValue(...).then(() => {
  // The value has actually been stored at this point.
});
SettingsStore.getValue(...); // this will return the value set in `setValue` above.

Watching for changes

Most use cases do not need to set up a watcher because they are able to react to changes as they are made, or the
changes which are made are not significant enough for it to matter. Watchers are intended to be used in scenarios where
it is important to react to changes made by other logged in devices. Typically, this would be done within the component
itself, however the component should not be aware of the intricacies of setting inversion or remapping to particular
data structures. Instead, a generic watcher interface is provided on SettingsStore to watch (and subsequently unwatch)
for changes in a setting.

An example of a watcher in action would be:

javascript
class MyComponent extends React.Component {
    settingWatcherRef = null;

    componentDidMount() {
        const callback = (settingName, roomId, level, newValAtLevel, newVal) => {
            this.setState({ color: newVal });
        };
        this.settingWatcherRef = SettingsStore.watchSetting("roomColor", "!example:matrix.org", callback);
    }

    componentWillUnmount() {
        SettingsStore.unwatchSetting(this.settingWatcherRef);
    }
}

Maintainers Reference

The granular settings system has a few complex parts to power it. This section is to document how the SettingsStore is
supposed to work.

General information

The SettingsStore uses the hardcoded LEVEL_ORDER constant to ensure that it is using the correct override procedure.
The array is checked from left to right, simulating the behaviour of overriding values from the higher levels. Each
level should be defined in this array, including default.

Handlers (src/settings/handlers/SettingsHandler.ts) represent a single level and are responsible for getting and
setting values at that level. Handlers also provide additional information to the SettingsStore such as if the level
is supported or if the current user may set values at the level. The SettingsStore will use the handler to enforce
checks and manipulate settings. Handlers are also responsible for dealing with migration patterns or legacy settings for
their level (for example, a setting being renamed or using a different key from other settings in the underlying store).
Handlers are provided to the SettingsStore via the LEVEL_HANDLERS constant. SettingsStore will optimize lookups by
only considering handlers that are supported on the platform.

Local echo is achieved through src/settings/handlers/LocalEchoWrapper.ts which acts as a wrapper around a given
handler. This is automatically applied to all defined LEVEL_HANDLERS and proxies the calls to the wrapped handler
where possible. The echo is achieved by a simple object cache stored within the class itself. The cache is invalidated
immediately upon the proxied save call succeeding or failing.

Controllers are notified of changes by the SettingsStore, and are given the opportunity to override values after the
SettingsStore has deemed the value calculated. Controllers are invoked as the last possible step in the code.

Features

See above for feature reference.

Watchers

Watchers can appear complicated under the hood: there is a central WatchManager which handles the actual invocation
of callbacks, and callbacks are managed by the SettingsStore by redirecting the caller's callback to a dedicated
callback. This is done so that the caller can reuse the same function as their callback without worrying about whether
or not it'll unsubscribe all watchers.

Setting changes are emitted into the default WatchManager, which calculates the new value for the setting. Ideally,
we'd also try and suppress updates which don't have a consequence on this value, however there's not an easy way to do
this. Instead, we just dispatch an update for all changes and leave it up to the consumer to deduplicate.

In practice, handlers which rely on remote changes (account data, room events, etc) will always attach a listener to the
MatrixClient. They then watch for changes to events they care about and send off appropriate updates to the
generalized WatchManager - a class specifically designed to deduplicate the logic of managing watchers. The handlers
which are localized to the local client (device) generally just trigger the WatchManager when they manipulate the
setting themselves as there's nothing to really 'watch'.


Skinning (`docs/skinning.md`)

Skinning

Skinning in the context of the react-sdk is component replacement rather than CSS. This means you can override (replace)
any accessible component in the project to implement custom behaviour, look & feel, etc. Depending on your approach,
overriding CSS classes to apply custom styling is also possible, though harder to do.

At present, the react-sdk offers no stable interface for components - this means properties and state can and do change
at any time without notice. Once we determine the react-sdk to be stable enough to use as a proper SDK, we will adjust
this policy. In the meantime, skinning is done completely at your own risk.

The approach you take is up to you - we suggest using a module replacement plugin, as found in
webpack, though you're free to use whichever build
system works for you. The react-sdk does not have any particular functions to call to load skins, so simply replace or
extend the components/stores/etc you're after and build. As a reminder though, this is done completely at your own risk
as we cannot guarantee a stable interface at this time.

Taking a look at element-web's approach to skinning may be worthwhile, as it
overrides some relatively simple components.


Theming (`docs/theming.md`)

Theming Element

Themes are a very basic way of providing simple alternative look & feels to the
Element app via CSS & custom imagery.

To define a theme for Element:

  1. Pick a name, e.g. teal. at time of writing we have light and dark.
  2. Fork res/themes/dark/css/dark.pcss to be teal.pcss
  3. Fork res/themes/dark/css/_base.pcss to be _teal.pcss
  4. Override variables in _teal.pcss as desired. You may wish to delete ones
    which don't differ from _base.pcss, to make it clear which are being
    overridden. If every single colour is being changed (as per _dark.pcss)
    then you might as well keep them all.
  5. Add the theme to the list of entrypoints in webpack.config.js
  6. Add the theme to the list of themes in theme.ts
  7. Sit back and admire your handywork.

In future, the assets for a theme will probably be gathered together into a
single directory tree.

Custom Themes

Themes derived from the built in themes may also be defined in settings.

Custom themes can also be added at runtime from a URL pointing at a JSON theme
definition: open the developer tools (/devtools) and pick Custom themes
under the Other category. Themes added this way remember the URL they came
from, so they can be re-downloaded from that same panel when the theme changes.

To avoid name collisions, the internal name of a theme is
custom-${theme.name}. So if you want to set the custom theme below as the
default theme, you would use default_theme: "custom-Electric Blue".

e.g. in config.json:

text
/* Detailed source-code truncated for AI context efficiency. */

compound may contain overrides for any semantic design token belonging to our design system. The above example shows how you might change the accent color to blue by setting the relevant semantic tokens to refer to blue base tokens.

All properties in fonts are optional, and will default to the standard Riot fonts.


Translating Dev (`docs/translating-dev.md`)

How to translate Element (Dev Guide)

Requirements

  • A working Development Setup
  • Latest LTS version of Node.js installed
  • Be able to understand English

Translating strings vs. marking strings for translation

Translating strings are done with the _t() function found in languageHandler.
It is recommended to call this function wherever you introduce a string constant which should be translated.
However, translating can not be performed until after the translation system has been initialized.
Thus, sometimes translation must be performed at a different location in the source code than where the string is introduced.
This breaks some tooling and makes it difficult to find translatable strings.
Therefore, there is the alternative _td() function which is used to mark strings for translation,
without actually performing the translation (which must still be performed separately, and after the translation system has been initialized).

Basically, whenever a translatable string is introduced, you should call either _t() immediately OR _td() and later _t().

Example:

text
// Module-level constant
const COLORS = {
    '#f8481c': _td('reddish orange'), // Can't call _t() here yet
    '#fc2647': _td('pinky red') // Use _td() instead so the text is picked up for translation anyway
}

// Function that is called some time after i18n has been loaded
function getColorName(hex) {
    return _t(COLORS[hex]); // Perform actual translation here
}

Key naming rules

These rules are based on https://github.com/element-hq/element-x-android/blob/develop/tools/localazy/README.md
At this time we are not trying to have a translation key per UI element as some methodologies use,
whilst that would offer the greatest flexibility, it would also make reuse between projects nigh impossible.
We are aiming for a set of common strings to be shared then some more localised translations per context they may appear in.

  1. Ensure the string doesn't already exist in a related project, such as https://localazy.com/p/element
  2. Keys for common strings, i.e. strings that can be used at multiple places must start by action_ if this is a verb, or common_ if not
  3. Keys for common accessibility strings must start by a11y_. Example: a11y_hide_password
  4. Otherwise, try to group keys logically and nest where appropriate, such as keyboard_ for strings relating to keyboard shortcuts.
  5. Ensure your translation keys do not include . or | or . Try to balance string length against descriptiveness.
  6. Key names should match the meaning and purpose of the translations as closely as they can. E.g. "button_click_biscuits" -> "Click for biscuits"

Adding new strings

  1. Check if the import import { _t } from ".../languageHandler"; is present. If not add it to the other import statements. Also import _td if needed.
  2. Add _t() to your string passing the translation key you come up with based on the rules above. If the string is introduced at a point before the translation system has not yet been initialized, use _td() instead, and call _t() at the appropriate time.
  3. Run pnpm i18n to add the keys to src/i18n/strings/en_EN.json
  4. Modify the new entries in src/i18n/strings/en_EN.json with the English (UK) translations for the added keys.

Editing non-English UK existing strings

Edits to existing non-en_EN strings should be performed only via Localazy.
There you can also require all translations to be redone if the meaning of the string has changed significantly.

Editing English UK (en_EN) strings

Edits to en_EN.json require a PR, since there is a high chance that a test covers the string in use and may be impacted if it were to change. This also gives us a clean change history.

When changing a string, be careful to rename the key if the meaning changes. For instance, if the key button_click_biscuits changed from "Click for biscuits" to "Click for vegetables", then they key should have changed to button_click_vegetables.

Removing existing strings

You can remove an existing string by removing the key from en_EN.json. Do not modify other language json files for this purpose.

Localazy will mark the keys you removed as deprecated. See https://localazy.com/docs/general/editing-source-language#source-key-states for more information about the difference between deprecated keys and deleted keys.

Adding variables inside a string.

  1. Extend your _t() call. Instead of _t(TKEY) use _t(TKEY, {})
  2. Decide how to name it. Please think about if the person who has to translate it can understand what it does. E.g. using the name 'recipient' is bad, because a translator does not know if it is the name of a person, an email address, a user ID, etc. Rather use e.g. recipientEmailAddress.
  3. Add it to the array in _t for example _t(TKEY, {variable: this.variable})
  4. Add the variable inside the string. The syntax for variables is %(variable)s. Please note the s at the end. The name of the variable has to match the previous used name.
  • You can use the special count variable to choose between multiple versions of the same string, in order to get the correct pluralization. E.g. _t('You have %(count)s new messages', { count: 2 }) would show 'You have 2 new messages', while _t('You have %(count)s new messages', { count: 1 }) would show 'You have one new message' (assuming a singular version of the string has been added to the translation file. See above). Passing in count is much preferred over having an if-statement choose the correct string to use, because some languages have much more complicated plural rules than english (e.g. they might need a completely different form if there are three things rather than two).
  • If you want to translate text that includes e.g. hyperlinks or other HTML you have to also use tag substitution, e.g. _t('<a>Click here!</a>', {}, { 'a': (sub) => <a>{sub}</a> }). If you don't do the tag substitution you will end up showing literally <a> rather than making a hyperlink.
  • You can also use React components with normal variable substitution if you want to insert HTML markup, e.g. _t('Your email address is %(emailAddress)s', { emailAddress: *{userEmailAddress}* }).

Things to know/Style Guides

  • Do not use _t() inside getDefaultProps: the translations aren't loaded when getDefaultProps is called, leading to missing translations. Use _td() to indicate that _t() will be called on the string later.
  • If using translated strings as constants, translated strings can't be in constants loaded at class-load time since the translations won't be loaded. Mark the strings using _td() instead and perform the actual translation later.
  • If a string is presented in the UI with punctuation like a full stop, include this in the translation strings, since punctuation varies between languages too.
  • Avoid "translation in parts", i.e. concatenating translated strings or using translated strings in variable substitutions. Context is important for translations, and translating partial strings this way is simply not always possible.
  • Concatenating strings often also introduces an implicit assumption about word order (e.g. that the subject of the sentence comes first), which is incorrect for many languages.
  • Translation 'smell test': If you have a string that does not begin with a capital letter (is not the start of a sentence) or it ends with e.g. ':' or a preposition (e.g. 'to') you should recheck that you are not trying to translate a partial sentence.
  • If you have multiple strings, that are almost identical, except some part (e.g. a word or two) it is still better to translate the full sentence multiple times. It may seem like inefficient repetition, but unlike programming where you try to minimize repetition, translation is much faster if you have many, full, clear, sentences to work with, rather than fewer, but incomplete sentence fragments.
  • Don't forget curly braces when you assign an expression to JSX attributes in the render method.

Translating (`docs/translating.md`)

How to translate Element

Requirements

  • Web Browser
  • Be able to understand English
  • Be able to understand the language you want to translate Element into

Join #element-translations:matrix.org

  1. Come and join https://matrix.to/#/#element-translations:matrix.org for general discussion
  2. Join https://matrix.to/#/#element-translators:matrix.org for language-specific rooms
  3. Read scrollback and/or ask if anyone else is working on your language, and co-ordinate if needed. In general little-or-no coordination is needed though :)

How to check if your language already is being translated

Go to https://localazy.com/p/element-web. If your language is listed then you can get started. Have a read
of https://localazy.com/docs/general/translating-strings if you need help getting started. If your language is not yet
listed please express your wishes to start translating it in the general discussion room linked above.

What are `%(something)s`?

These things are placeholders that are expanded when displayed by Element. They can be room names, usernames or similar.
If you find one, you can move to the right place for your language, but not delete it as the variable will be missing if you do.
A special case is %(count)s as this is also used to determine which pluralisation is used.

What are `Something`

These things are markup tags, they encapsulate sections of translations to be marked up, with links, buttons, emphasis and such.
You must keep these markers surrounding the equivalent string in your language that needs to be marked up.

When will my translations be available?

We automatically pull changes from Localazy 3 times a week, so your translations should be available at https://develop.element.io
within a few days of you submitting them and them being approved. They will then also be included in the following release cycle.


Updates (`docs/updates.md`)

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

Windows

On Windows the update mechanism used is 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
using the newer JSON format as documented here.


Usercontent (`docs/usercontent.md`)

Usercontent

While decryption itself is safe to be done without a sandbox,
letting the browser and user interact with the resulting data may be dangerous,
previously usercontent.riot.im was used to act as a sandbox on a different origin to close the attack surface,
it is now possible to do by using a combination of a sandboxed iframe and some code written into the app which consumes this SDK.

Usercontent is an iframe sandbox target for allowing a user to safely download a decrypted attachment from a sandboxed origin where it cannot be used to XSS your Element session out from under you.

Its function is to create an Object URL for the user/browser to use but bound to an origin different to that of the Element instance to protect against XSS.

It exposes a function over a postMessage API, when sent an object with the matching fields to render a download link with the Object URL:

json5
{
    imgSrc: "", // the src of the image to display in the download link
    imgStyle: "", // the style to apply to the image
    style: "", // the style to apply to the download link
    download: "", // download attribute to pass to the <a/> tag
    textContent: "", // the text to put inside the download link
    blob: "", // the data blob to wrap in an object url and allow the user to download
}

If only imgSrc, imgStyle and style are passed then just update the existing link without overwriting other things about it.

It is expected that this target be available at usercontent/ relative to the root of the app, this can be seen in element-web's webpack config.

PDF viewer

The PDF viewer (behind the feature_pdf_viewer lab) renders documents with pdf.js,
using the same technique: the document is drawn inside a second usercontent target, expected at usercontent/pdf/
relative to the root of the app, embedded as an iframe with sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox".
Without allow-same-origin the iframe gets an opaque origin, so everything pdf.js builds from the untrusted
document — the canvases, the selectable text layer, link annotations, and the worker that parses the file —
is kept away from the app's storage, session and DOM. Popups are allowed so that a link in a document can open
in a new tab, and leave the iframe's restrictions behind so that the tab it opens is an ordinary one.

The app (PdfViewer.tsx) fetches and decrypts the attachment, checks its size and signature, and then talks to
the iframe over postMessage. The protocol is defined in src/usercontent/pdf/protocol.ts; in short, the app sends

json5
{ type: "load", data: ArrayBuffer, position: { page, scale, left, top } } // the document, and where to open it
{ type: "go_to_page", page: 3 }

and the iframe answers with ready, loaded (page count), page (the page now at the top), position (the
reading position to remember) and error. The iframe posts ready to its parent, addressed to the origin it was
served by, with one end of a MessageChannel; everything else travels over that channel, so no message needs a
wildcard target. The app only takes the port from a ready posted by its own iframe's window with the "null"
origin a sandboxed iframe has, and both sides check the shape of every message before acting on it.

Two consequences of the opaque origin are worth knowing about:

  • A worker's script has to be same-origin with the document starting it, and nothing the app serves is
    same-origin with an opaque origin. pdf.js's worker is therefore bundled into the iframe's script as a string
    and started from a blob URL. Chromium will not start a module worker from a blob URL in an iframe with an opaque origin,
    so a one-line classic worker import()s it instead, which all engines accept.
  • 'self' in a Content-Security-Policy has no meaning for an opaque origin (WebKit refuses the iframe's own
    scripts under it), so the iframe's policy is applied from its script once everything it needs from the app
    has loaded. From then on the iframe may start blob workers and use inline styles, and nothing else: no fetch,
    image, script or form can carry a decrypted document anywhere.

Widget Layouts (`docs/widget-layouts.md`)

Widget layout support

Rooms can have a default widget layout to auto-pin certain widgets, make the container different
sizes, etc. These are defined through the io.element.widgets.layout state event (empty state key).

Full example content:

json5
{
    widgets: {
        "first-widget-id": {
            container: "top",
            index: 0,
            width: 60,
            height: 40,
        },
        "second-widget-id": {
            container: "right",
        },
    },
}

As shown, there are two containers possible for widgets. These containers have different behaviour
and interpret the other options differently.

`top` container

This is the "App Drawer" or any pinned widgets in a room. This is by far the most versatile container
though does introduce potential usability issues upon members of the room (widgets take up space and
therefore fewer messages can be shown).

The index for a widget determines which order the widgets show up in from left to right. Widgets
without an index will show up as the rightmost widgets. Tiebreaks (same index or multiple defined
without an index) are resolved by comparing widget IDs. A maximum of 3 widgets can be in the top
container - any which exceed this will be ignored (placed into the right container). Smaller numbers
represent leftmost widgets.

The width is relative width within the container in percentage points. This will be clamped to a
range of 0-100 (inclusive). The widgets will attempt to scale to relative proportions when more than
100% space is allocated. For example, if 3 widgets are defined at 40% width each then the client will
attempt to show them at 33% width each.

Note that the client may impose minimum widths on the widgets, such as a 10% minimum to avoid pinning
hidden widgets. In general, widgets defined in the 30-70% range each will be free of these restrictions.

The height is not in fact applied per-widget but is recorded per-widget for potential future
capabilities in future containers. The top container will take the tallest height and use that for
the height of the whole container, and thus all widgets in that container. The height is relative
to the container, like with width, meaning that 100% will consume as much space as the client is
willing to sacrifice to the widget container. Like with width, the client may impose minimums to avoid
the container being uselessly small. Heights in the 30-100% range are generally acceptable. The height
is also clamped to be within 0-100, inclusive.

`right` container

This is the default container and has no special configuration. Widgets which overflow from the top
container will be put in this container instead. Putting a widget in the right container does not
automatically show it - it only mentions that widgets should not be in another container.

The behaviour of this container may change in the future.


Windows Requirements (`docs/windows-requirements.md`)

Windows

Requirements to build

We rely on Github Actions windows-2025 as per the workflow.

If you want to build Element Desktop on Windows, make sure that the following tools are installed on your system.

You can install the above tools using Chocolatey:

cmd
choco install --no-progress -y git nodejs-lts pnpm

Once installed make sure all those utilities are accessible in your PATH.

Native modules are consumed as prebuilt binaries, so no compiler toolchain is required.
See native-node-modules.md for details, including how to
build the arm64 package from an x64 host.


Changelogs CHANGELOG 2022 (`docs/changelogs/CHANGELOG-2022.md`)

Changes in [1.11.17](https://github.com/vector-im/element-web/releases/tag/v1.11.17) (2022-12-21)

✨ Features

  • Add inline code formatting to rich text editor (#9720).
  • Add emoji handling for plain text mode of the new rich text editor (#9727).
  • Overlay virtual room call events into main timeline (#9626). Fixes #22929.
  • Adds a new section under "Room Settings" > "Roles & Permissions" which adds the possibility to multiselect users from this room and grant them more permissions. (#9596). Contributed by @GoodGuyMarco.
  • Add emoji handling for rich text mode (#9661).
  • Add setting to hide bold notifications (#9705).
  • Further password reset flow enhancements (#9662).
  • Snooze the bulk unverified sessions reminder on dismiss (#9706).
  • Honor advanced audio processing settings when recording voice messages (#9610). Contributed by @MrAnno.
  • Improve the visual balance of bubble layout (#9704).
  • Add config setting to disable bulk unverified sessions nag (#9657).
  • Only display bulk unverified sessions nag when current sessions is verified (#9656).
  • Separate labs and betas more clearly (#8969). Fixes #22706.
  • Show user an error if we fail to create a DM for verification. (#9624).

🐛 Bug Fixes

  • Prevent unnecessary m.direct updates (#9805). Fixes #24059.
  • Fix checkForPreJoinUISI for thread roots (#9803). Fixes #24054.
  • Load RTE components only when RTE labs is enabled (#9804).
  • Fix issue where thread panel did not update correctly (#9746). Fixes #23971.
  • Remove async call to get virtual room from room load (#9743). Fixes #23968.
  • Check each thread for unread messages. (#9723).
  • Device manage - handle sessions that don't support encryption (#9717). Fixes #23722.
  • Fix hover state for formatting buttons (Rich text editor) (fix vector-im/element-web/issues/23832) (#9715).
  • Don't allow group calls to be unterminated (#9710).
  • Fix replies to emotes not showing as inline (#9707). Fixes #23903.
  • Update copy of 'Change layout' button to match Element Call (#9703).
  • Fix call splitbrains when switching between rooms (#9692).
  • bugfix: fix an issue where the Notifier would incorrectly fire for non-timeline events (#9664). Fixes #17263.
  • Fix power selector being wrongly disabled for admins themselves (#9681). Fixes #23882.
  • Show day counts in call durations (#9641).

Changes in [1.11.16](https://github.com/vector-im/element-web/releases/tag/v1.11.16) (2022-12-06)

✨ Features

  • Further improve replies (#6396). Fixes #19074, #18194 #18027 and #19179.
  • Enable users to join group calls from multiple devices (#9625).
  • fix(visual): make cursor a pointer for summaries (#9419). Contributed by @r00ster91.
  • Add placeholder for rich text editor (#9613).
  • Consolidate public room search experience (#9605). Fixes #22846.
  • New password reset flow (#9581). Fixes #23131.
  • Device manager - add tooltip to device details toggle (#9594).
  • sliding sync: add lazy-loading member support (#9530).
  • Limit formatting bar offset to top of composer (#9365). Fixes #12359. Contributed by @owi92.

🐛 Bug Fixes

  • Fix issues around up arrow event edit shortcut (#9645). Fixes #18497 and #18964.
  • Fix search not being cleared when clicking on a result (#9635). Fixes #23845.
  • Fix screensharing in 1:1 calls (#9612). Fixes #23808.
  • Fix the background color flashing when joining a call (#9640).
  • Fix the size of the 'Private space' icon (#9638).
  • Fix reply editing in rich text editor (https (#9615).
  • Fix thread list jumping back down while scrolling (#9606). Fixes #23727.
  • Fix regression with TimelinePanel props updates not taking effect (#9608). Fixes #23794.
  • Fix form tooltip positioning (#9598). Fixes #22861.
  • Extract Search handling from RoomView into its own Component (#9574). Fixes #498.
  • Fix call splitbrains when switching between rooms (#9692).
  • [Backport staging] Fix replies to emotes not showing as inline (#9708).

Changes in [1.11.15](https://github.com/vector-im/element-web/releases/tag/v1.11.15) (2022-11-22)

✨ Features

  • Make clear notifications work with threads (#9575). Fixes #23751.
  • Change "None" to "Off" in notification options (#9539). Contributed by @Arnei.
  • Advanced audio processing settings (#8759). Fixes #6278. Contributed by @MrAnno.
  • Add way to create a user notice via config.json (#9559).
  • Improve design of the rich text editor (#9533). Contributed by @florianduros.
  • Enable user to zoom beyond image size (#5949). Contributed by @jaiwanth-v.
  • Fix: Move "Leave Space" option to the bottom of space context menu (#9535). Contributed by @hanadi92.

🐛 Bug Fixes

  • Make build scripts work on NixOS (#23740).
  • Fix integration manager get_open_id_token action and add E2E tests (#9520).
  • Fix links being mangled by markdown processing (#9570). Fixes #23743.
  • Fix: inline links selecting radio button (#9543). Contributed by @hanadi92.
  • Fix wrong error message in registration when phone number threepid is in use. (#9571). Contributed by @bagvand.
  • Fix missing avatar for show current profiles (#9563). Fixes #23733.
  • Fix read receipts trickling down correctly (#9567). Fixes #23746.
  • Resilience fix for homeserver without thread notification support (#9565).
  • Don't switch to the home page needlessly after leaving a room (#9477).
  • Differentiate download and decryption errors when showing images (#9562). Fixes #3892.
  • Close context menu when a modal is opened to prevent user getting stuck (#9560). Fixes #15610 and #10781.
  • Fix TimelineReset handling when no room associated (#9553).
  • Always use current profile on thread events (#9524). Fixes #23648.
  • Fix ThreadView tests not using thread flag (#9547). Contributed by @MadLittleMods.
  • Handle deletion of m.call events (#9540). Fixes #23663.
  • Fix incorrect notification count after leaving a room with notifications (#9518). Contributed by @Arnei.

Changes in [1.11.14](https://github.com/vector-im/element-web/releases/tag/v1.11.14) (2022-11-08)

✨ Features

  • Loading threads with server-side assistance (#9356). Fixes #21807, #21799, #21911, #22141, #22157, #22641, #22501 #22438 and #21678. Contributed by @justjanne.
  • Make thread replies trigger a room list re-ordering (#9510). Fixes #21700.
  • Device manager - add extra details to device security and renaming (#9501). Contributed by @kerryarchibald.
  • Add plain text mode to the wysiwyg composer (#9503). Contributed by @florianduros.
  • Sliding Sync: improve sort order, show subspace rooms, better tombstoned room handling (#9484).
  • Device manager - add learn more popups to filtered sessions section (#9497). Contributed by @kerryarchibald.
  • Show thread notification if thread timeline is closed (#9495). Fixes #23589.
  • Add message editing to wysiwyg composer (#9488). Contributed by @florianduros.
  • Device manager - confirm sign out of other sessions (#9487). Contributed by @kerryarchibald.
  • Automatically request logs from other users in a call when submitting logs (#9492).
  • Add thread notification with server assistance (MSC3773) (#9400). Fixes #21114, #21413, #21416, #21433, #21481, #21798, #21823 #23192 and #21765.
  • Support for login + E2EE set up with QR (#9403). Contributed by @hughns.
  • Allow pressing Enter to send messages in new composer (#9451). Contributed by @andybalaam.

🐛 Bug Fixes

  • Fix regressions around media uploads failing and causing soft crashes (#9549). Fixes matrix-org/element-web-rageshakes#16831, matrix-org/element-web-rageshakes#16824 matrix-org/element-web-rageshakes#16810 and vector-im/element-web#23641.
  • Fix /myroomavatar slash command (#9536). Fixes matrix-org/synapse#14321.
  • Fix config.json failing to load for Jitsi wrapper in non-root deployment (#23577).
  • Fix NotificationBadge unsent color (#9522). Fixes #23646.
  • Fix room list sorted by recent on app startup (#9515). Fixes #23635.
  • Reset custom power selector when blurred on empty (#9508). Fixes #23481.
  • Reinstate timeline/redaction callbacks when updating notification state (#9494). Fixes #23554.
  • Only render NotificationBadge when needed (#9493). Fixes #23584.
  • Fix embedded Element Call screen sharing (#9485). Fixes #23571.
  • Send Content-Type: application/json header for integration manager /register API (#9490). Fixes #23580.
  • Fix joining calls without audio or video inputs (#9486). Fixes #23511.
  • Ensure spaces in the spotlight dialog have rounded square avatars (#9480). Fixes #23515.
  • Only show mini avatar uploader in room intro when no avatar yet exists (#9479). Fixes #23552.
  • Fix threads fallback incorrectly targets root event (#9229). Fixes #23147.
  • Align video call icon with banner text (#9460).
  • Set relations helper when creating event tile context menu (#9253). Fixes #22018.
  • Device manager - put client/browser device metadata in correct section (#9447). Contributed by @kerryarchibald.
  • Update the room unread notification counter when the server changes the value without any related read receipt (#9438).

Changes in [1.11.13](https://github.com/vector-im/element-web/releases/tag/v1.11.13) (2022-11-01)

🐛 Bug Fixes

  • Fix default behavior of Room.getBlacklistUnverifiedDevices (#2830). Contributed by @duxovni.
  • Catch server versions API call exception when starting the client (#2828). Fixes vector-im/element-web#23634.
  • Fix authedRequest including Authorization: Bearer undefined for password resets (#2822). Fixes vector-im/element-web#23655.

Changes in [1.11.12](https://github.com/vector-im/element-web/releases/tag/v1.11.12) (2022-10-26)

🐛 Bug Fixes

  • Fix config.json failing to load for Jitsi wrapper in non-root deployment (#23577).

Changes in [1.11.11](https://github.com/vector-im/element-web/releases/tag/v1.11.11) (2022-10-25)

✨ Features

  • Device manager - tweak string formatting of default device name (#23457).
  • Add Element Call participant limit (#23431).
  • Add Element Call brand (#23443).
  • Include a file-safe room name and ISO date in chat exports (#9440). Fixes #21812 and #19724.
  • Room call banner (#9378). Fixes #23453. Contributed by @toger5.
  • Device manager - spinners while devices are signing out (#9433). Fixes #15865.
  • Device manager - silence call ringers when local notifications are silenced (#9420).
  • Pass the current language to Element Call (#9427).
  • Hide screen-sharing button in Element Call on desktop (#9423).
  • Add reply support to WysiwygComposer (#9422). Contributed by @florianduros.
  • Disconnect other connected devices (of the same user) when joining an Element call (#9379).
  • Device manager - device tile main click target (#9409).
  • Add formatting buttons to the rich text editor (#9410). Contributed by @florianduros.
  • Device manager - current session context menu (#9386).
  • Remove piwik config fallback for privacy policy URL (#9390).
  • Add the first step to integrate the matrix wysiwyg composer (#9374). Contributed by @florianduros.
  • Device manager - UA parsing tweaks (#9382).
  • Device manager - remove client information events when disabling setting (#9384).
  • Add Element Call participant limit (#9358).
  • Add Element Call room settings (#9347).
  • Device manager - render extended device information (#9360).
  • New group call experience: Room header and PiP designs (#9351).
  • Pass language to Jitsi Widget (#9346). Contributed by @Fox32.
  • Add notifications and toasts for Element Call calls (#9337).
  • Device manager - device type icon (#9355).
  • Delete the remainder of groups (#9357). Fixes #22770.
  • Device manager - display client information in device details (#9315).

🐛 Bug Fixes

  • Send Content-Type: application/json header for integration manager /register API (#9490). Fixes #23580.
  • Make ErrorView & CompatibilityView scrollable (#23468). Fixes #23376.
  • Device manager - put client/browser device metadata in correct section (#9447).
  • update the room unread notification counter when the server changes the value without any related read receipt (#9438).
  • Don't show call banners in video rooms (#9441).
  • Prevent useContextMenu isOpen from being true if the button ref goes away (#9418). Fixes matrix-org/element-web-rageshakes#15637.
  • Automatically focus the WYSIWYG composer when you enter a room (#9412).
  • Improve the tooltips on the call lobby join button (#9428).
  • Pass the homeserver's base URL to Element Call (#9429). Fixes #23301.
  • Better accommodate long room names in call toasts (#9426).
  • Hide virtual widgets from the room info panel (#9424). Fixes #23494.
  • Inhibit clicking on sender avatar in threads list (#9417). Fixes #23482.
  • Correct the dir parameter of MSC3715 (#9391). Contributed by @dhenneke.
  • Use a more correct subset of users in /remakeolm developer command (#9402).
  • use correct default for notification silencing (#9388). Fixes #23456.
  • Device manager - eagerly create m.local_notification_settings events (#9353).
  • Close incoming Element call toast when viewing the call lobby (#9375).
  • Always allow enabling sending read receipts (#9367). Fixes #23433.
  • Fixes (vector-im/element-web/issues/22609) where the white theme is not applied when white -> dark -> white sequence is done. (#9320). Contributed by @florianduros.
  • Fix applying programmatically set height for "top" room layout (#9339). Contributed by @Fox32.

Changes in [1.11.10](https://github.com/vector-im/element-web/releases/tag/v1.11.10) (2022-10-11)

🐛 Bug Fixes

  • Use correct default for notification silencing (#9388). Fixes vector-im/element-web#23456.

Changes in [1.11.9](https://github.com/vector-im/element-web/releases/tag/v1.11.9) (2022-10-11)

Deprecations

  • Legacy Piwik config.json option piwik.policy_url is deprecated in favour of privacy_policy_url. Support will be removed in the next release.

✨ Features

  • Device manager - select all devices (#9330). Contributed by @kerryarchibald.
  • New group call experience: Call tiles (#9332).
  • Add Shift key to FormatQuote keyboard shortcut (#9298). Contributed by @owi92.
  • Device manager - sign out of multiple sessions (#9325). Contributed by @kerryarchibald.
  • Display push toggle for web sessions (MSC3890) (#9327).
  • Add device notifications enabled switch (#9324).
  • Implement push notification toggle in device detail (#9308).
  • New group call experience: Starting and ending calls (#9318).
  • New group call experience: Room header call buttons (#9311).
  • Make device ID copyable in device list (#9297). Contributed by @duxovni.
  • Use display name instead of user ID when rendering power events (#9295).
  • Read receipts for threads (#9239). Fixes #23191.

🐛 Bug Fixes

  • Use the correct sender key when checking shared secret (#2730). Fixes vector-im/element-web#23374.
  • Fix device selection in pre-join screen for Element Call video rooms (#9321). Fixes #23331.
  • Don't render a 1px high room topic if the room topic is empty (#9317). Contributed by @Arnei.
  • Don't show feedback prompts when that UIFeature is disabled (#9305). Fixes #23327.
  • Fix soft crash around unknown room pills (#9301). Fixes matrix-org/element-web-rageshakes#15465.
  • Fix spaces feedback prompt wrongly showing when feedback is disabled (#9302). Fixes #23314.
  • Fix tile soft crash in ReplyInThreadButton (#9300). Fixes matrix-org/element-web-rageshakes#15493.

Changes in [1.11.8](https://github.com/vector-im/element-web/releases/tag/v1.11.8) (2022-09-28)

🐛 Bug Fixes

  • Bump IDB crypto store version (#2705).

Changes in [1.11.7](https://github.com/vector-im/element-web/releases/tag/v1.11.7) (2022-09-28)

🔒 Security

Changes in [1.11.6](https://github.com/vector-im/element-web/releases/tag/v1.11.6) (2022-09-20)

✨ Features

  • Element Call video rooms (#9267).
  • Device manager - rename session (#9282).
  • Allow widgets to read related events (#9210). Contributed by @dhenneke.
  • Device manager - logout of other session (#9280).
  • Device manager - logout current session (#9275).
  • Device manager - verify other devices (#9274).
  • Allow integration managers to remove users (#9211).
  • Device manager - add verify current session button (#9252).
  • Add NotifPanel dot back. (#9242). Fixes #17641.
  • Implement MSC3575: Sliding Sync (#8328).
  • Add the clipboard read permission for widgets (#9250). Contributed by @stefanmuhle.

🐛 Bug Fixes

  • Make autocomplete pop-up wider in thread view (#9289).
  • Fix soft crash around inviting invalid MXIDs in start DM on first message flow (#9281). Fixes matrix-org/element-web-rageshakes#15060 and matrix-org/element-web-rageshakes#15140.
  • Fix in-reply-to previews not disappearing when swapping rooms (#9278).
  • Fix invalid instanceof operand window.OffscreenCanvas (#9276). Fixes #23275.
  • Fix memory leak caused by unremoved listener (#9273).
  • Fix thumbnail generation when offscreen canvas fails (#9272). Fixes #23265.
  • Prevent sliding sync from showing a room under multiple sublists (#9266).
  • Fix tile crash around tooltipify links (#9270). Fixes #23253.
  • Device manager - filter out nulled metadatas in device tile properly (#9251).
  • Fix a sliding sync bug which could cause rooms to loop (#9268).
  • Remove the grey gradient on images in bubbles in the timeline (#9241). Fixes #21651.
  • Fix html export not including images (#9260). Fixes #22059.
  • Fix possible soft crash from a race condition in space hierarchies (#9254). Fixes matrix-org/element-web-rageshakes#15225.
  • Disable all types of autocorrect, -complete, -capitalize, etc on Spotlight's search field (#9259).
  • Handle M_INVALID_USERNAME on /register/available (#9237). Fixes #23161.
  • Fix issue with quiet zone around QR code (#9243). Fixes #23199.

Changes in [1.11.5](https://github.com/vector-im/element-web/releases/tag/v1.11.5) (2022-09-13)

✨ Features

  • Device manager - hide unverified security recommendation when only current session is unverified (#9228). Contributed by @kerryarchibald.
  • Device manager - scroll to filtered list from security recommendations (#9227). Contributed by @kerryarchibald.
  • Device manager - updated dropdown style in filtered device list (#9226). Contributed by @kerryarchibald.
  • Device manager - device type and verification icons on device tile (#9197). Contributed by @kerryarchibald.

🐛 Bug Fixes

  • Description of DM room with more than two other people is now being displayed correctly (#9231). Fixes #23094.
  • Fix voice messages with multiple composers (#9208). Fixes #23023. Contributed by @grimhilt.
  • Fix suggested rooms going missing (#9236). Fixes #23190.
  • Fix tooltip infinitely recursing (#9235). Fixes matrix-org/element-web-rageshakes#15107, matrix-org/element-web-rageshakes#15093 matrix-org/element-web-rageshakes#15092 and matrix-org/element-web-rageshakes#15077.
  • Fix plain text export saving (#9230). Contributed by @jryans.
  • Add missing space in SecurityRoomSettingsTab (#9222). Contributed by @gefgu.
  • Make use of js-sdk roomNameGenerator to handle i18n for generated room names (#9209). Fixes #21369.
  • Fix progress bar regression throughout the app (#9219). Fixes #23121.
  • Reuse empty string & space string logic for event types in devtools (#9218). Fixes #23115.

Changes in [1.11.4](https://github.com/vector-im/element-web/releases/tag/v1.11.4) (2022-08-31)

🔒 Security

Learn more about what we've been up to at https://element.io/blog/element-web-desktop-1-11-4-a-security-update-deferred-dms-and-more/
Find more details of the vulnerabilities at https://matrix.org/blog/2022/08/31/security-releases-matrix-js-sdk-19-4-0-and-matrix-react-sdk-3-53-0

✨ Features

  • Device manager - scroll to filtered list from security recommendations (#9227). Contributed by @kerryarchibald.
  • Device manager - updated dropdown style in filtered device list (#9226). Contributed by @kerryarchibald.
  • Device manager - device type and verification icons on device tile (#9197). Contributed by @kerryarchibald.
  • Ignore unreads in low priority rooms in the space panel (#6518). Fixes #16836.
  • Release message right-click context menu out of labs (#8613).
  • Device manager - expandable session details in device list (#9188). Contributed by @kerryarchibald.
  • Device manager - device list filtering (#9181). Contributed by @kerryarchibald.
  • Device manager - add verification details to session details (#9187). Contributed by @kerryarchibald.
  • Device manager - current session expandable details (#9185). Contributed by @kerryarchibald.
  • Device manager - security recommendations section (#9179). Contributed by @kerryarchibald.
  • The Welcome Home Screen: Return Button (#9089). Fixes #22917. Contributed by @justjanne.
  • Device manager - label devices as inactive (#9175). Contributed by @kerryarchibald.
  • Device manager - other sessions list (#9155). Contributed by @kerryarchibald.
  • Implement MSC3846: Allowing widgets to access TURN servers (#9061).
  • Allow widgets to send/receive to-device messages (#8885).

🐛 Bug Fixes

  • Add super cool feature (#9222). Contributed by @gefgu.
  • Make use of js-sdk roomNameGenerator to handle i18n for generated room names (#9209). Fixes #21369.
  • Fix progress bar regression throughout the app (#9219). Fixes #23121.
  • Reuse empty string & space string logic for event types in devtools (#9218). Fixes #23115.
  • Reduce amount of requests done by the onboarding task list (#9194). Fixes #23085. Contributed by @justjanne.
  • Avoid hardcoding branding in user onboarding (#9206). Fixes #23111. Contributed by @justjanne.
  • End jitsi call when member is banned (#8879). Contributed by @maheichyk.
  • Fix context menu being opened when clicking message action bar buttons (#9200). Fixes #22279 and #23100.
  • Add gap between checkbox and text in report dialog following the same pattern (8px) used in the gap between the two buttons. It fixes vector-im/element-web#23060 (#9195). Contributed by @gefgu.
  • Fix url preview AXE and layout issue & add percy test (#9189). Fixes #23083.
  • Wrap long space names (#9201). Fixes #23095.
  • Attempt to fix Failed to execute 'removeChild' on 'Node' (#9196).
  • Fix soft crash around space hierarchy changing between spaces (#9191). Fixes matrix-org/element-web-rageshakes#14613.
  • Fix soft crash around room view store metrics (#9190). Fixes matrix-org/element-web-rageshakes#14361.
  • Fix the same person appearing multiple times when searching for them. (#9177). Fixes #22851.
  • Fix space panel subspace indentation going missing (#9167). Fixes #23049.
  • Fix invisible power levels tile when showing hidden events (#9162). Fixes #23013.
  • Space panel accessibility improvements (#9157). Fixes #22995.
  • Fix inverted logic for showing UserWelcomeTop component (#9164). Fixes #23037.

Changes in [1.11.3](https://github.com/vector-im/element-web/releases/tag/v1.11.3) (2022-08-16)

✨ Features

  • Improve auth aria attributes and semantics (#22948).
  • Device manager - New device tile info design (#9122). Contributed by @kerryarchibald.
  • Device manager generic settings subsection component (#9147). Contributed by @kerryarchibald.
  • Migrate the hidden read receipts flag to new "send read receipts" option (#9141).
  • Live location sharing - share location at most every 5 seconds (#9148). Contributed by @kerryarchibald.
  • Increase max length of voice messages to 15m (#9133). Fixes #18620.
  • Move pin drop out of labs (#9135).
  • Start DM on first message (#8612). Fixes #14736.
  • Remove "Add Space" button from RoomListHeader when user cannot create spaces (#9129).
  • The Welcome Home Screen: Dedicated Download Apps Dialog (#9120). Fixes #22921. Contributed by @justjanne.
  • The Welcome Home Screen: "Submit Feedback" pane (#9090). Fixes #22918. Contributed by @justjanne.
  • New User Onboarding Task List (#9083). Fixes #22919. Contributed by @justjanne.
  • Add support for disabling spell checking (#8604). Fixes #21901.
  • Live location share - leave maximised map open when beacons expire (#9098). Contributed by @kerryarchibald.

🐛 Bug Fixes

  • Some slash-commands (/myroomnick) have temporarily been disabled before the first message in a DM is sent. (#9193).
  • Use stable reference for active tab in tabbedView (#9145). Contributed by @kerryarchibald.
  • Fix pillification sometimes doubling up (#9152). Fixes #23036.
  • Fix highlights not being applied to plaintext messages (#9126). Fixes #22787.
  • Fix dismissing edit composer when change was undone (#9109). Fixes #22932.
  • 1-to-1 DM rooms with bots now act like DM rooms instead of multi-user-rooms before (#9124). Fixes #22894.
  • Apply inline start padding to selected lines on modern layout only (#9006). Fixes #22768. Contributed by @luixxiul.
  • Peek into world-readable rooms from spotlight (#9115). Fixes #22862.
  • Use default styling on nested numbered lists due to MD being sensitive (#9110). Fixes #22935.
  • Fix replying using chat effect commands (#9101). Fixes #22824.

Changes in [1.11.2](https://github.com/vector-im/element-web/releases/tag/v1.11.2) (2022-08-03)

✨ Features

  • Live location share - focus on user location on list item click (#9051). Contributed by @kerryarchibald.
  • Live location sharing - don't trigger unread counts for beacon location events (#9071). Contributed by @kerryarchibald.
  • Support for sending voice messages as replies and in threads (#9097). Fixes #22031.
  • Add Reply in thread button to the right-click message context-menu (#9004). Fixes #22745.
  • Starred_Messages_Feature_Contd_II/Outreachy (#9086).
  • Use "frequently used emojis" for autocompletion in composer (#8998). Fixes #18978. Contributed by @grimhilt.
  • Improve clickability of view source event toggle button (#9068). Fixes #21856. Contributed by @luixxiul.
  • Improve clickability of "collapse" link button on bubble layout (#9037). Fixes #22864. Contributed by @luixxiul.
  • Starred_Messages_Feature/Outreachy (#8842).
  • Implement Use Case Selection screen (#8984). Contributed by @justjanne.
  • Live location share - handle insufficient permissions in location sharing (#9047). Contributed by @kerryarchibald.
  • Improve _FilePanel.scss (#9031). Contributed by @luixxiul.
  • Improve spotlight accessibility by adding context menus (#8907). Fixes #20875 and #22675. Contributed by @justjanne.

🐛 Bug Fixes

  • Replace mask-images with svg components in MessageActionBar (#9088). Fixes #22912. Contributed by @kerryarchibald.
  • Unbreak in-app permalink tooltips (#9087). Fixes #22874.
  • Show a back button when viewing a space member (#9095). Fixes #22898.
  • Align the right edge of info tile lines with normal ones on IRC layout (#9058). Fixes #22871. Contributed by @luixxiul.
  • Prevent email verification from overriding existing sessions (#9075). Fixes #22881. Contributed by @justjanne.
  • Fix wrong buttons being used when exploring public rooms (#9062). Fixes #22862.
  • Re-add padding to generic event list summary on IRC layout (#9063). Fixes #22869. Contributed by @luixxiul.
  • Joining federated rooms via the spotlight search should no longer cause a "No known servers" error. (#9055). Fixes #22845. Contributed by @Half-Shot.

Changes in [1.11.1](https://github.com/vector-im/element-web/releases/tag/v1.11.1) (2022-07-26)

✨ Features

  • Enable URL tooltips on hover for Element Desktop (#22286). Fixes undefined/element-web#6532.
  • Hide screenshare button in video rooms on Desktop (#9045).
  • Add a developer command to reset Megolm and Olm sessions (#9044).
  • add spaces to TileErrorBoundary (#9012). Contributed by @HarHarLinks.
  • Location sharing - add localised strings to map (#9025). Fixes #21443. Contributed by @kerryarchibald.
  • Added trim to ignore whitespaces in email check (#9027). Contributed by @ankur12-1610.
  • Improve _GenericEventListSummary.scss (#9005). Contributed by @luixxiul.
  • Live location share - tiles without tile server (PSG-591) (#8962). Contributed by @kerryarchibald.
  • Add option to display tooltip on link hover (#8394). Fixes #21907.
  • Support a module API surface for custom functionality (#8246).
  • Adjust encryption copy when creating a video room (#8989). Fixes #22737.
  • Add bidirectonal isolation for pills (#8985). Contributed by @sha-265.
  • Delabs Show current avatar and name for users in message history (#8764). Fixes #22336.
  • Live location share - open latest location in map site (#8981). Contributed by @kerryarchibald.
  • Improve LinkPreviewWidget (#8881). Fixes #22634. Contributed by @luixxiul.
  • Render HTML topics in rooms on space home (#8939).
  • Hide timestamp on event tiles being edited on every layout (#8956). Contributed by @luixxiul.
  • Introduce new copy icon (#8942).
  • Allow finding group DMs by members in spotlight (#8922). Fixes #22564. Contributed by @justjanne.
  • Live location share - explicitly stop beacons replaced beacons (#8933). Contributed by @kerryarchibald.
  • Remove unpin from widget kebab menu (#8924).
  • Live location share - redact related locations on beacon redaction (#8926). Contributed by @kerryarchibald.
  • Live location share - disallow message pinning (#8928). Contributed by @kerryarchibald.

🐛 Bug Fixes

  • Remove the ability to hide yourself in video rooms (#22806). Fixes #22805.
  • Unbreak in-app permalink tooltips (#9100).
  • Add space for the stroke on message editor on IRC layout (#9030). Fixes #22785. Contributed by @luixxiul.
  • Fix pinned messages not re-linkifying on edit (#9042). Fixes #22726.
  • Don't unnecessarily persist the host signup dialog (#9043). Fixes #22778.
  • Fix URL previews causing messages to become unrenderable (#9028). Fixes #22766.
  • Fix event list summaries including invalid events (#9041). Fixes #22790.
  • Correct accessibility labels for unread rooms in spotlight (#9003). Contributed by @justjanne.
  • Enable search strings highlight on bubble layout (#9032). Fixes #22786. Contributed by @luixxiul.
  • Unbreak URL preview for formatted links with tooltips (#9022). Fixes #22764.
  • Re-add margin to tiles based on EventTileBubble (#9015). Fixes #22772. Contributed by @luixxiul.
  • Fix Shortcut prompt for Search showing in minimized Roomlist (#9014). Fixes #22739. Contributed by @justjanne.
  • Fix avatar position on event info line for hidden events on a thread (#9019). Fixes #22777. Contributed by @luixxiul.
  • Fix lost padding of event tile info line (#9009). Fixes #22754 and #22759. Contributed by @luixxiul.
  • Align verification bubble with normal event tiles on IRC layout (#9001). Fixes #22758. Contributed by @luixxiul.
  • Ensure timestamp on generic event list summary is not hidden from TimelineCard (#9000). Fixes #22755. Contributed by @luixxiul.
  • Fix headings margin on security user settings tab (#8826). Contributed by @luixxiul.
  • Fix timestamp position on file panel (#8976). Fixes #22718. Contributed by @luixxiul.
  • Stop using :not() pseudo class for mx_GenericEventListSummary (#8944). Fixes #22602. Contributed by @luixxiul.
  • Don't show the same user twice in Spotlight (#8978). Fixes #22697.
  • Align the right edge of expand / collapse link buttons of generic event list summary in bubble layout with a variable (#8992). Fixes #22743. Contributed by @luixxiul.
  • Display own avatars on search results panel in bubble layout (#8990). Contributed by @luixxiul.
  • Fix text flow of thread summary content on threads list (#8991). Fixes #22738. Contributed by @luixxiul.
  • Fix the size of the clickable area of images (#8987). Fixes #22282.
  • Fix font size of MessageTimestamp on TimelineCard (#8950). Contributed by @luixxiul.
  • Improve security room settings tab style rules (#8844). Fixes #22575. Contributed by @luixxiul.
  • Align E2E icon and avatar of info tile in compact modern layout (#8965). Fixes #22652. Contributed by @luixxiul.
  • Fix clickable area of general event list summary toggle (#8979). Fixes #22722. Contributed by @luixxiul.
  • Fix resizing room topic (#8966). Fixes #22689.
  • Dismiss the search dialogue when starting a DM (#8967). Fixes #22700.
  • Fix "greyed out" text style inconsistency on search result panel (#8974). Contributed by @luixxiul.
  • Add top padding to EventTilePreview loader (#8977). Fixes #22719. Contributed by @luixxiul.
  • Fix read receipts group position on TimelineCard in compact modern/group layout (#8971). Fixes #22715. Contributed by @luixxiul.
  • Fix calls on homeservers without the unstable thirdparty endpoints. (#8931). Fixes #21680. Contributed by @deepbluev7.
  • Enable ReplyChain text to be expanded on IRC layout (#8959). Fixes #22709. Contributed by @luixxiul.
  • Fix hidden timestamp on message edit history dialog (#8955). Fixes #22701. Contributed by @luixxiul.
  • Enable ReplyChain text to be expanded on bubble layout (#8958). Fixes #22709. Contributed by @luixxiul.
  • Fix expand/collapse state wrong in metaspaces (#8952). Fixes #22632.
  • Location (live) share replies now provide a fallback content (#8949).
  • Fix space settings not opening for script-created spaces (#8957). Fixes #22703.
  • Respect filename field on m.file events (#8951).
  • Fix PlatformSettingsHandler always returning true due to returning a Promise (#8954). Fixes #22616.
  • Improve high-contrast support for spotlight (#8948). Fixes #22481. Contributed by @justjanne.
  • Fix wrong assertions that all media events have a mimetype (#8946). Fixes matrix-org/element-web-rageshakes#13727.
  • Make invite dialogue fixed height (#8934). Fixes #22659.
  • Fix all megolm error reported as unknown (#8916).
  • Remove line-height declarations from _ReplyTile.scss (#8932). Fixes #22687. Contributed by @luixxiul.
  • Reduce video rooms log spam (#8913).
  • Correct new search input’s rounded corners (#8921). Fixes #22576. Contributed by @justjanne.
  • Align unread notification dot on threads list in compact modern=group layout (#8911). Fixes #22677. Contributed by @luixxiul.

Changes in [1.11.0](https://github.com/vector-im/element-web/releases/tag/v1.11.0) (2022-07-05)

🚨 BREAKING CHANGES

  • Remove Piwik support (#8835).

✨ Features

  • Document how to configure a custom home.html. (#21066). Contributed by @johannes-krude.
  • Move New Search Experience out of beta (#8859). Contributed by @justjanne.
  • Switch video rooms to spotlight layout when in PiP mode (#8912). Fixes #22574.
  • Live location sharing - render message deleted tile for redacted beacons (#8905). Contributed by @kerryarchibald.
  • Improve view source dialog style (#8883). Fixes #22636. Contributed by @luixxiul.
  • Improve integration manager dialog style (#8888). Fixes #22642. Contributed by @luixxiul.
  • Implement MSC3827: Filtering of /publicRooms by room type (#8866). Fixes #22578.
  • Show chat panel when opening a video room with unread messages (#8812). Fixes #22527.
  • Live location share - forward latest location (#8860). Contributed by @kerryarchibald.
  • Allow integration managers to validate user identity after opening (#8782). Contributed by @Half-Shot.
  • Create a common header on right panel cards on BaseCard (#8808). Contributed by @luixxiul.
  • Integrate searching public rooms and people into the new search experience (#8707). Fixes #21354 and #19349. Contributed by @justjanne.
  • Bring back waveform for voice messages and retain seeking (#8843). Fixes #21904.
  • Improve colors in settings (#7283).
  • Keep draft in composer when a slash command syntax errors (#8811). Fixes #22384.
  • Release video rooms as a beta feature (#8431).
  • Clarify logout key backup warning dialog. Contributed by @notramo. (#8741). Fixes #15565. Contributed by @MadLittleMods.
  • Slightly improve the look of the Message edits dialog (#8763). Fixes #22410.
  • Add support for MD / HTML in room topics (#8215). Fixes #5180. Contributed by @Johennes.
  • Live location share - link to timeline tile from share warning (#8752). Contributed by @kerryarchibald.
  • Improve composer visiblity (#8578). Fixes #22072 and #17362.
  • Makes the avatar of the user menu non-draggable (#8765). Contributed by @luixxiul.
  • Improve widget buttons behaviour and layout (#8734).
  • Use AccessibleButton for 'Reset All' link button on SetupEncryptionBody (#8730). Contributed by @luixxiul.
  • Adjust message timestamp position on TimelineCard in non-bubble layouts (#8745). Fixes #22426. Contributed by @luixxiul.
  • Use AccessibleButton for 'In reply to' link button on ReplyChain (#8726). Fixes #22407. Contributed by @luixxiul.
  • Live location share - enable reply and react to tiles (#8721). Contributed by @kerryarchibald.
  • Change dash to em dash issues fixed (#8455). Fixes #21895. Contributed by @goelesha.

🐛 Bug Fixes

  • Reduce video rooms log spam (#22665).
  • Connect to Jitsi unmuted by default (#22660). Fixes #22637.
  • Work around a Jitsi bug with display name encoding (#22525). Fixes #22521.
  • Make invite dialogue fixed height (#8945).
  • Correct issue with tab order in new search experience (#8919). Fixes #22670. Contributed by @justjanne.
  • Clicking location replies now redirects to the replied event instead of opening the map (#8918). Fixes #22667.
  • Keep clicks on pills within the app (#8917). Fixes #22653.
  • Don't overlap tile bubbles with timestamps in modern layout (#8908). Fixes #22425.
  • Connect to Jitsi unmuted by default (#8909).
  • Maximize width value of display name on TimelineCard with IRC/modern layout (#8904). Fixes #22651. Contributed by @luixxiul.
  • Align the avatar and the display name on TimelineCard (#8900). Contributed by @luixxiul.
  • Remove inline margin from reactions row on IRC layout (#8891). Fixes #22644. Contributed by @luixxiul.
  • Align "From a thread" on search result panel on IRC layout (#8892). Fixes #22645. Contributed by @luixxiul.
  • Display description of E2E advanced panel as subsection text (#8889). Contributed by @luixxiul.
  • Remove inline end margin from images on file panel (#8886). Fixes #22640. Contributed by @luixxiul.
  • Disable option to Quote when we don't have sufficient permissions (#8893). Fixes #22643.
  • Add padding to font scaling loader for message bubble layout (#8875). Fixes #22626. Contributed by @luixxiul.
  • Set 100% max-width to display name on reply tiles (#8867). Fixes #22615. Contributed by @luixxiul.
  • Fix alignment of pill letter (#8874). Fixes #22622. Contributed by @luixxiul.
  • Move the beta pill to the right side and display the pill on video room only (#8873). Fixes #22619 and #22620. Contributed by @luixxiul.
  • Stop using absolute property to place beta pill on RoomPreviewCard (#8872). Fixes #22617. Contributed by @luixxiul.
  • Make the pill text single line (#8744). Fixes #22427. Contributed by @luixxiul.
  • Hide overflow of public room description on spotlight dialog result (#8870). Contributed by @luixxiul.
  • Fix position of message action bar on the info tile on TimelineCard in message bubble layout (#8865). Fixes #22614. Contributed by @luixxiul.
  • Remove inline start margin from display name on reply tiles on TimelineCard (#8864). Fixes #22613. Contributed by @luixxiul.
  • Improve homeserver dropdown dialog styling (#8850). Fixes #22552. Contributed by @justjanne.
  • Fix crash when drawing blurHash for portrait videos PSB-139 (#8855). Fixes #22597. Contributed by @andybalaam.
  • Fix grid blowout on pinned event tiles (#8816). Fixes #22543. Contributed by @luixxiul.
  • Fix temporary sync errors if there's weird settings stored in account data (#8857).
  • Fix reactions row overflow and gap between reactions (#8813). Fixes #22093. Contributed by @luixxiul.
  • Fix issues with the Create new room button in Spotlight (#8851). Contributed by @justjanne.
  • Remove margin from E2E icon between avatar and hidden event (#8584). Fixes #22186. Contributed by @luixxiul.
  • Fix waveform on a message bubble (#8852). Contributed by @luixxiul.
  • Location sharing maps are now loaded after reconnection (#8848). Fixes #20993.
  • Update the avatar mask so it doesn’t cut off spaces’ avatars anymore (#8849). Contributed by @justjanne.
  • Add a bit of safety around timestamp handling for threads (#8845).
  • Remove top margin from event tile on a narrow viewport (#8814). Contributed by @luixxiul.
  • Fix keyboard shortcuts on settings tab being wrapped (#8825). Fixes #22547. Contributed by @luixxiul.
  • Add try-catch around blurhash loading (#8830).
  • Prevent new composer from overflowing from non-breakable text (#8829). Fixes #22507. Contributed by @justjanne.
  • Use common subheading on sidebar user settings tab (#8823). Contributed by @luixxiul.
  • Fix clickable area of advanced toggle on appearance user settings tab (#8820). Fixes #22546. Contributed by @luixxiul.
  • Disable redacting reactions if we don't have sufficient permissions (#8767). Fixes #22262.
  • Update the live timeline when the JS SDK resets it (#8806). Fixes #22421.
  • Fix flex blowout on image reply (#8809). Fixes #22509 and #22510. Contributed by @luixxiul.
  • Enable background color on hover for chat panel and thread panel (#8644). Fixes #22273. Contributed by @luixxiul.
  • Fix #20026: send read marker as soon as we change it (#8802). Fixes #20026. Contributed by @andybalaam.
  • Allow AppTiles to shrink as much as necessary (#8805). Fixes #22499.
  • Make widgets in video rooms immutable again (#8803). Fixes #22497.
  • Use MessageActionBar style declarations on pinned message card (#8757). Fixes #22444. Contributed by @luixxiul.
  • Expire video member events after 1 hour (#8776).
  • Name lists on invite dialog (#8046). Fixes #21400 and #19463. Contributed by @luixxiul.
  • Live location share - show loading UI for beacons with start timestamp in the future (#8775). Fixes #22437. Contributed by @kerryarchibald.
  • Fix scroll jump issue with the composer (#8788). Fixes #22464.
  • Fix the incorrect nesting of download button on MessageActionBar (#8785). Contributed by @luixxiul.
  • Revert link color change in composer (#8784). Fixes #22468.
  • Fix 'Logout' inline link on the splash screen (#8770). Fixes #22449. Contributed by @luixxiul.
  • Fix disappearing widget poput button when changing the widget layout (#8754).
  • Reduce gutter with the new read receipt UI (#8736). Fixes #21890.
  • Add ellipsis effect to hidden beacon status (#8755). Fixes #22441. Contributed by @luixxiul.
  • Make the pill on the basic message composer compatible with display name in RTL languages (#8758). Fixes #22445. Contributed by @luixxiul.
  • Prevent the banner text from being selected, replacing the spacing values with the variable (#8756). Fixes #22442. Contributed by @luixxiul.
  • Ensure the first device on a newly-registered account gets cross-signed properly (#8750). Fixes #21977. Contributed by @duxovni.
  • Hide live location option in threads composer (#8746). Fixes #22424. Contributed by @kerryarchibald.
  • Make sure MessageTimestamp is not hidden by EventTile_line on TimelineCard (#8748). Contributed by @luixxiul.
  • Make PiP motion smoother and react to window resizes correctly (#8747). Fixes #22292.
  • Prevent Invite and DevTools dialogs from being cut off (#8646). Fixes #20911 and undefined/matrix-react-sdk#8165. Contributed by @justjanne.
  • Squish event bubble tiles less (#8740).
  • Use random widget IDs for video rooms (#8739). Fixes #22417.
  • Fix read avatars overflow from the right chat panel with a maximized widget on bubble message layout (#8470). Contributed by @luixxiul.
  • Fix CallView crash (#8735). Fixes #22394.

Changes in [1.10.15](https://github.com/vector-im/element-web/releases/tag/v1.10.15) (2022-06-14)

🐛 Bug Fixes

  • Fix missing element desktop preferences (#8798). Contributed by @t3chguy.

Changes in [1.10.14](https://github.com/vector-im/element-web/releases/tag/v1.10.14) (2022-06-07)

✨ Features

  • Make Lao translation available (#22358). Fixes #22327.
  • Option to disable hardware acceleration on Element Desktop (#22295). Contributed by @novocaine.
  • Configure custom home.html via .well-known/matrix/client["io.element.embedded_pages"]["home_url"] for all your element-web/desktop users (#7790). Contributed by @johannes-krude.
  • Live location sharing - open location in OpenStreetMap (#8695). Contributed by @kerryarchibald.
  • Show a dialog when Jitsi encounters an error (#8701). Fixes #22284.
  • Add support for setting the avatar_url of widgets by integration managers. (#8550). Contributed by @Fox32.
  • Add an option to ignore (block) a user when reporting their events (#8471).
  • Add the option to disable hardware acceleration (#8655). Contributed by @novocaine.
  • Slightly better presentation of read receipts to screen reader users (#8662). Fixes #22293. Contributed by @pvagner.
  • Add jump to related event context menu item (#6775). Fixes #19883.
  • Add public room directory hook (#8626).

🐛 Bug Fixes

  • Stop Jitsi if we time out while connecting to a video room (#22301). Fixes #22283.
  • Remove inline margin from UTD error message inside a reply tile on ThreadView (#8708). Fixes #22376. Contributed by @luixxiul.
  • Move unread notification dots of the threads list to the expected position (#8700). Fixes #22350. Contributed by @luixxiul.
  • Prevent overflow of grid items on a bubble with UTD generally (#8697). Contributed by @luixxiul.
  • Create 'Unable To Decrypt' grid layout for hidden events on a bubble layout (#8704). Fixes #22365. Contributed by @luixxiul.
  • Fix - AccessibleButton does not set disabled attribute (#8682). Contributed by @kerryarchibald.
  • Fix font not resetting when logging out (#8670). Fixes #17228.
  • Fix local aliases section of room settings not working for some homeservers (ie (#8698). Fixes #22337.
  • Align EventTile_line with display name on message bubble (#8692). Fixes #22343. Contributed by @luixxiul.
  • Convert references to direct chat -> direct message (#8694). Contributed by @novocaine.
  • Improve combining diacritics for U+20D0 to U+20F0 in Chrome (#8687).
  • Make the empty thread panel fill BaseCard (#8690). Fixes #22338. Contributed by @luixxiul.
  • Fix edge case around composer handling gendered facepalm emoji (#8686).
  • Fix a grid blowout due to nowrap displayName on a bubble with UTD (#8688). Fixes #21914. Contributed by @luixxiul.
  • Apply the same max-width to image tile on the thread timeline as message bubble (#8669). Fixes #22313. Contributed by @luixxiul.
  • Fix dropdown button size for picture-in-picture CallView (#8680). Fixes #22316. Contributed by @luixxiul.
  • Live location sharing - fix square border for image-less avatar (PSF-1052) (#8679). Contributed by @kerryarchibald.
  • Stop connecting to a video room if the widget messaging disappears (#8660).
  • Fix file button and audio player overflowing from message bubble (#8666). Fixes #22308. Contributed by @luixxiul.
  • Don't show broken composer format bar when selection is whitespace (#8673). Fixes #10788.
  • Fix media upload http 413 handling (#8674).
  • Fix emoji picker for editing thread responses (#8671). Fixes matrix-org/element-web-rageshakes#13129.
  • Map attribution while sharing live location is now visible (#8621). Fixes #22236. Contributed by @weeman1337.
  • Fix info tile overlapping the time stamp on TimelineCard (#8639). Fixes #22256. Contributed by @luixxiul.
  • Fix position of wide images on IRC / modern layout (#8667). Fixes #22309. Contributed by @luixxiul.
  • Fix other user's displayName being wrapped on the bubble message layout (#8456). Fixes #22004. Contributed by @luixxiul.
  • Set spacing declarations to elements in mx_EventTile_mediaLine (#8665). Fixes #22307. Contributed by @luixxiul.
  • Fix wide image overflowing from the thumbnail container (#8663). Fixes #22303. Contributed by @luixxiul.
  • Fix styles of "Show all" link button on ReactionsRow (#8658). Fixes #22300. Contributed by @luixxiul.
  • Automatically log in after registration (#8654). Fixes #19305. Contributed by @justjanne.
  • Fix offline status in window title not working reliably (#8656).
  • Align input area with event body's first letter in a thread on IRC/modern layout (#8636). Fixes #22252. Contributed by @luixxiul.
  • Fix crash on null idp for SSO buttons (#8650). Contributed by @hughns.
  • Don't open the regular browser or our context menu on right-clicking the Options button in the message action bar (#8648). Fixes #22279.
  • Show notifications even when Element is focused (#8590). Contributed by @sumnerevans.
  • Remove padding from the buttons on edit message composer of a event tile on a thread (#8632). Contributed by @luixxiul.
  • ensure metaspace changes correctly notify listeners (#8611). Fixes #21006. Contributed by @justjanne.
  • Hide image banner on stickers, they have a tooltip already (#8641). Fixes #22244.
  • Adjust EditMessageComposer style declarations (#8631). Fixes #22231. Contributed by @luixxiul.

Changes in [1.10.13](https://github.com/vector-im/element-web/releases/tag/v1.10.13) (2022-05-24)

✨ Features

  • Go to space landing page when clicking on a selected space (#6442). Fixes #20296.
  • Fall back to untranslated string rather than showing missing translation error (#8609).
  • Show file name and size on images on hover (#6511). Fixes #18197.
  • Iterate on search results for message bubbles (#7047). Fixes #20315.
  • registration: redesign email verification page (#8554). Fixes #21984.
  • Show full thread message in hover title on thread summary (#8568). Fixes #22037.
  • Tweak video rooms copy (#8582). Fixes #22176.
  • Live location share - beacon tooltip in maximised view (#8572).
  • Add dialog to navigate long room topics (#8517). Fixes #9623.
  • Change spaceroomfacepile tooltip if memberlist is shown (#8571). Fixes #17406.
  • Improve message editing UI (#8483). Fixes #9752 and #22108.
  • Make date changes more obvious (#6410). Fixes #16221.
  • Enable forwarding static locations (#8553).
  • Log TimelinePanel debugging info when opening the bug report modal (#8502).
  • Improve welcome screen, add opt-out analytics (#8474). Fixes #21946.
  • Converting selected text to MD link when pasting a URL (#8242). Fixes #21634. Contributed by @Sinharitik589.
  • Support Inter on custom themes (#8399). Fixes #16293.
  • Add a Copy link button to the right-click message context-menu labs feature (#8527).
  • Move widget screenshots labs flag to devtools (#8522).
  • Remove some labs features which don't get used or create maintenance burden: custom status, multiple integration managers, and do not disturb (#8521).
  • Add a way to toggle ScrollPanel and TimelinePanel debug logs (#8513).
  • Spaces: remove blue beta dot (#8511). Fixes #22061.
  • Order new search dialog results by recency (#8444).
  • Improve pills (#6398). Fixes #16948 and #21281.
  • Add a way to maximize/pin widget from the PiP view (#7672). Fixes #20723.
  • Iterate video room designs in labs (#8499).
  • Improve UI/UX in calls (#7791). Fixes #19937.
  • Add ability to change audio and video devices during a call (#7173). Fixes #15595.

🐛 Bug Fixes

  • Fix video rooms sometimes connecting muted when they shouldn't (#22125).
  • Avoid flashing the 'join conference' button at the user in video rooms (#22120).
  • Fully close Jitsi conferences on errors (#22060).
  • Fix click behavior of notification badges on spaces (#8627). Fixes #22241.
  • Add missing return values in Read Receipt animation code (#8625). Fixes #22175.
  • Fix 'continue' button not working after accepting identity server terms of service (#8619). Fixes #20003.
  • Proactively fix stuck devices in video rooms (#8587). Fixes #22131.
  • Fix position of the message action bar on left side bubbles (#8398). Fixes #21879. Contributed by @luixxiul.
  • Fix edge case thread summaries around events without a msgtype (#8576).
  • Fix favourites metaspace not updating (#8594). Fixes #22156.
  • Stop spaces from displaying as rooms in new breadcrumbs (#8595). Fixes #22165.
  • Fix avatar position of hidden event on ThreadView (#8592). Fixes #22199. Contributed by @luixxiul.
  • Fix MessageTimestamp position next to redacted messages on IRC/modern layout (#8591). Fixes #22181. Contributed by @luixxiul.
  • Fix padding of messages in threads (#8574). Contributed by @luixxiul.
  • Enable overflow of hidden events content (#8585). Fixes #22187. Contributed by @luixxiul.
  • Increase composer line height to avoid cutting off emoji (#8583). Fixes #22170.
  • Don't consider threads for breaking continuation until actually created (#8581). Fixes #22164.
  • Fix displaying hidden events on threads (#8555). Fixes #22058. Contributed by @luixxiul.
  • Fix button width and align 絵文字 (emoji) on the user panel (#8562). Fixes #22142. Contributed by @luixxiul.
  • Standardise the margin for settings tabs (#7963). Fixes #20767. Contributed by @yuktea.
  • Fix room history not being visible even if we have historical keys (#8563). Fixes #16983.
  • Fix oblong avatars in video room lobbies (#8565).
  • Update thread summary when latest event gets decrypted (#8564). Fixes #22151.
  • Fix codepath which can wrongly cause automatic space switch from all rooms (#8560). Fixes #21373.
  • Fix effect of URL preview toggle not updating live (#8561). Fixes #22148.
  • Fix visual bugs on AccessSecretStorageDialog (#8160). Fixes #19426. Contributed by @luixxiul.
  • Fix the width bounce of the clock on the AudioPlayer (#8320). Fixes #21788. Contributed by @luixxiul.
  • Hide the verification left stroke only on the thread list (#8525). Fixes #22132. Contributed by @luixxiul.
  • Hide recently_viewed dropdown when other modal opens (#8538). Contributed by @yaya-usman.
  • Only jump to date after pressing the 'go' button (#8548). Fixes #20799.
  • Fix download button not working on events that were decrypted too late (#8556). Fixes #19427.
  • Align thread summary button with bubble messages on the left side (#8388). Fixes #21873. Contributed by @luixxiul.
  • Fix unresponsive notification toggles (#8549). Fixes #22109.
  • Set color-scheme property in themes (#8547). Fixes #22124.
  • Improve the styling of error messages during search initialization. (#6899). Fixes #19245 and #18164. Contributed by @KalleStruik.
  • Don't leave button tooltips open when closing modals (#8546). Fixes #22121.
  • update matrix-analytics-events (#8543).
  • Handle Jitsi Meet crashes more gracefully (#8541).
  • Fix regression around pasting links (#8537). Fixes #22117.
  • Fixes suggested room not ellipsized on shrinking (#8536). Contributed by @yaya-usman.
  • Add global spacing between display name and location body (#8523). Fixes #22111. Contributed by @luixxiul.
  • Add box-shadow to the reply preview on the main (left) panel only (#8397). Fixes #21894. Contributed by @luixxiul.
  • Set line-height: 1 to RedactedBody inside GenericEventListSummary for IRC/modern layout (#8529). Fixes #22112. Contributed by @luixxiul.
  • Fix position of timestamp on the chat panel in IRC layout and message edits history modal window (#8464). Fixes #22011 and #22014. Contributed by @luixxiul.
  • Fix unexpected and inconsistent inheritance of line-height property for mx_TextualEvent (#8485). Fixes #22041. Contributed by @luixxiul.
  • Set the same margin to the right side of NewRoomIntro on TimelineCard (#8453). Contributed by @luixxiul.
  • Remove duplicate tooltip from user pills (#8512).
  • Set max-width for MLocationBody and MLocationBody_map by default (#8519). Fixes #21983. Contributed by @luixxiul.
  • Simplify ReplyPreview UI implementation (#8516). Fixes #22091. Contributed by @luixxiul.
  • Fix thread summary overflow on narrow message panel on bubble message layout (#8520). Fixes #22097. Contributed by @luixxiul.
  • Live location sharing - refresh beacon timers on tab becoming active (#8515).
  • Enlarge emoji again (#8509). Fixes #22086.
  • Order receipts with the most recent on the right (#8506). Fixes #22044.
  • Disconnect from video rooms when leaving (#8500).
  • Fix soft crash around threads when room isn't yet in store (#8496). Fixes #22047.
  • Fix reading of cached room device setting values (#8491).
  • Add loading spinners to threads panels (#8490). Fixes #21335.
  • Fix forwarding UI papercuts (#8482). Fixes #17616.

Changes in [1.10.12](https://github.com/vector-im/element-web/releases/tag/v1.10.12) (2022-05-10)

✨ Features

  • Made the location map change the cursor to a pointer so it looks like it's clickable (https (#8451). Fixes #21991. Contributed by @Odyssey346.
  • Implement improved spacing for the thread list and timeline (#8337). Fixes #21759. Contributed by @luixxiul.
  • LLS: expose way to enable live sharing labs flag from location dialog (#8416).
  • Fix source text boxes in View Source modal should have full width (#8425). Fixes #21938. Contributed by @EECvision.
  • Read Receipts: never show +1, if it’s just 4, show all of them (#8428). Fixes #21935.
  • Add opt-in analytics to onboarding tasks (#8409). Fixes #21705.
  • Allow user to control if they are signed out of all devices when changing password (#8259). Fixes #2671.
  • Implement new Read Receipt design (#8389). Fixes #20574.
  • Stick connected video rooms to the top of the room list (#8353).
  • LLS: fix jumpy maximised map (#8387).
  • Persist audio and video mute state in video rooms (#8376).
  • Forcefully disconnect from video rooms on logout and tab close (#8375).
  • Add local echo of connected devices in video rooms (#8368).
  • Improve text of account deactivation dialog (#8371). Fixes #17421.
  • Live location sharing: own live beacon status on maximised view (#8374).
  • Show a lobby screen in video rooms (#8287).
  • Settings toggle to disable Composer Markdown (#8358). Fixes #20321.
  • Cache localStorage objects for SettingsStore (#8366).
  • Bring View Source back from behind developer mode (#8369). Fixes #21771.

🐛 Bug Fixes

  • Fix Jitsi Meet getting wedged at startup in some cases (#21995).
  • Fix camera getting muted when disconnecting from a video room (#21958).
  • Fix race conditions around threads (#8448). Fixes #21627.
  • Fix reading of cached room device setting values (#8495).
  • Fix issue with dispatch happening mid-dispatch due to js-sdk emit (#8473). Fixes #22019.
  • Match MSC behaviour for threads when disabled (thread-aware mode) (#8476). Fixes #22033.
  • Specify position of DisambiguatedProfile inside a thread on bubble message layout (#8452). Fixes #21998. Contributed by @luixxiul.
  • Location sharing: do not trackuserlocation in location picker (#8466). Fixes #22013.
  • fix text and map indent in thread view (#8462). Fixes #21997.
  • Live location sharing: don't group beacon info with room creation summary (#8468).
  • Don't linkify code blocks (#7859). Fixes #9613.
  • read receipts: improve tooltips to show names of users (#8438). Fixes #21940.
  • Fix poll overflowing a reply tile on bubble message layout (#8459). Fixes #22005. Contributed by @luixxiul.
  • Fix text link buttons on UserInfo panel (#8247). Fixes #21702. Contributed by @luixxiul.
  • Clear local storage settings handler cache on logout (#8454). Fixes #21994.
  • Fix jump to bottom button being always displayed in non-overflowing timelines (#8460). Fixes #22003.
  • fix timeline search with empty text box should do nothing (#8262). Fixes #21714. Contributed by @EECvision.
  • Fixes "space panel kebab menu is rendered out of view on sub spaces" (#8350). Contributed by @yaya-usman.
  • Add margin to the location map inside ThreadView (#8442). Fixes #21982. Contributed by @luixxiul.
  • Patch: "Reloading the registration page should warn about data loss" (#8377). Contributed by @yaya-usman.
  • Live location sharing: fix safari timestamps pt 2 (#8443).
  • Fix issue with thread notification state ignoring initial events (#8417). Fixes #21927.
  • Fix event text overflow on bubble message layout (#8391). Fixes #21882. Contributed by @luixxiul.
  • Disable the message action bar when hovering over the 1px border between threads on the list (#8429). Fixes #21955. Contributed by @luixxiul.
  • correctly align read receipts to state events in bubble layout (#8419). Fixes #21899.
  • Fix issue with underfilled timelines when barren of content (#8432). Fixes #21930.
  • Fix baseline misalignment of thread panel summary by deduplication (#8413).
  • Fix editing of non-html replies (#8418). Fixes #21928.
  • Read Receipts "Fall from the Sky" (#8414). Fixes #21888.
  • Make read receipts handle nullable roomMembers correctly (#8410). Fixes #21896.
  • Don't form continuations on either side of a thread root (#8408). Fixes #20908.
  • Fix centering issue with sticker placeholder (#8404). Fixes #18014 and #6449.
  • Disable download option on
  • Fix infinite loop when pinning/unpinning persistent widgets (#8396). Fixes #21864.
  • Tweak ReadReceiptGroup to better handle disambiguation (#8402). Fixes #21897.
  • stop the bottom edge of buttons getting clipped in devtools (#8400).
  • Fix issue with threads timelines with few events cropping events (#8392). Fixes #20594.
  • Changed font-weight to 400 to support light weight font (#8345). Fixes #21171. Contributed by @goelesha.
  • Fix issue with thread panel not updating when it loads on first render (#8382). Fixes #21737.
  • fix: "Mention highlight and cursor hover highlight has different corner radius" (#8384). Contributed by @yaya-usman.
  • Fix regression around haveRendererForEvent for hidden events (#8379). Fixes #21862 and #21725.
  • Fix regression around the room list treeview keyboard a11y (#8385). Fixes #21436.
  • Remove float property to let the margin between events appear on bubble message layout (#8373). Fixes #21861. Contributed by @luixxiul.
  • Fix race in Registration between server change and flows fetch (#8359). Fixes #21800.
  • fix rainbow breaks compound emojis (#8245). Fixes #21371. Contributed by @EECvision.
  • Fix RightPanelStore handling first room on app launch wrong (#8370). Fixes #21741.
  • Fix UnknownBody error message unalignment (#8346). Fixes #21828. Contributed by @luixxiul.
  • Use -webkit-line-clamp for the room header topic overflow (#8367). Fixes #21852. Contributed by @luixxiul.
  • Fix issue with ServerInfo crashing the modal (#8364).
  • Fixes around threads beta in degraded mode (#8319). Fixes #21762.

Changes in [1.10.11](https://github.com/vector-im/element-web/releases/tag/v1.10.11) (2022-04-26)

✨ Features

  • Handle forced disconnects from Jitsi (#21697). Fixes #21517.
  • Improve performance of switching to rooms with lots of servers and ACLs (#8347).
  • Avoid a reflow when setting caret position on an empty composer (#8348).
  • Add message right-click context menu as a labs feature (#5672).
  • Live location sharing - basic maximised beacon map (#8310).
  • Live location sharing - render users own beacons in timeline (#8296).
  • Improve Threads beta around degraded mode (#8318).
  • Live location sharing - beacon in timeline happy path (#8285).
  • Add copy button to View Source screen (#8278). Fixes #21482. Contributed by @olivialivia.
  • Add heart effect (#6188). Contributed by @CicadaCinema.
  • Update new room icon (#8239).

🐛 Bug Fixes

  • Fix: "Code formatting button does not escape backticks" (#8181). Contributed by @yaya-usman.
  • Fix beta indicator dot causing excessive CPU usage (#8340). Fixes #21793.
  • Fix overlapping timestamps on empty messages (#8205). Fixes #21381. Contributed by @goelesha.
  • Fix power selector not showing up in user info when state_default undefined (#8297). Fixes #21669.
  • Avoid looking up settings during timeline rendering (#8313). Fixes #21740.
  • Fix a soft crash with video rooms (#8333).
  • Fixes call tiles overflow (#8096). Fixes #20254. Contributed by @luixxiul.
  • Fix a bug with emoji autocomplete sorting where adding the final ":" would cause the emoji with the typed shortcode to no longer be at the top of the autocomplete list. (#8086). Fixes #19302. Contributed by @commonlawfeature.
  • Fix image preview sizing for edge cases (#8322). Fixes #20088.
  • Refactor SecurityRoomSettingsTab and remove unused state (#8306). Fixes matrix-org/element-web-rageshakes#12002.
  • Don't show the prompt to enable desktop notifications immediately after registration (#8274).
  • Stop tracking threads if threads support is disabled (#8308). Fixes #21766.
  • Fix some issues with threads rendering (#8305). Fixes #21670.
  • Fix threads rendering issue in Safari (#8298). Fixes #21757.
  • Fix space panel width change on hovering over space item (#8299). Fixes #19891.
  • Hide the reply in thread button in deployments where beta is forcibly disabled (#8294). Fixes #21753.
  • Prevent soft crash around room list header context menu when space changes (#8289). Fixes matrix-org/element-web-rageshakes#11416, matrix-org/element-web-rageshakes#11692, matrix-org/element-web-rageshakes#11739, matrix-org/element-web-rageshakes#11772, matrix-org/element-web-rageshakes#11891 matrix-org/element-web-rageshakes#11858 and matrix-org/element-web-rageshakes#11456.
  • When selecting reply in thread on a thread response open existing thread (#8291). Fixes #21743.
  • Handle thread bundled relationships coming from the server via MSC3666 (#8292). Fixes #21450.
  • Fix: Avatar preview does not update when same file is selected repeatedly (#8288). Fixes #20098.
  • Fix a bug where user gets a warning when changing powerlevel from Admin to custom level (100) (#8248). Fixes #21682. Contributed by @Jumeb.
  • Use a consistent alignment for all text items in a list (#8276). Fixes #21731. Contributed by @luixxiul.
  • Fixes button labels being collapsed per a character in CJK languages (#8212). Fixes #21287. Contributed by @luixxiul.
  • Fix: Remove jittery timeline scrolling after jumping to an event (#8263).
  • Fix regression of edits showing up in the timeline with hidden events shown (#8260). Fixes #21694.
  • Fix reporting events not working (#8257). Fixes #21713.
  • Make Jitsi widgets in video rooms immutable (#8244). Fixes #21647.
  • Fix: Ensure links to events scroll the correct events into view (#8250). Fixes #19934.

Changes in [1.10.10](https://github.com/vector-im/element-web/releases/tag/v1.10.10) (2022-04-14)

🐛 Bug Fixes

  • Fixes around threads beta in degraded mode (#8319). Fixes #21762.

Changes in [1.10.9](https://github.com/vector-im/element-web/releases/tag/v1.10.9) (2022-04-12)

✨ Features

  • Release threads as a beta feature (#8081). Fixes #21351.
  • More video rooms design updates (#8222).
  • Update video rooms to new design specs (#8207). Fixes #21515, #21516 #21519 and #21526.
  • Live Location Sharing - left panel warning with error (#8201).
  • Live location sharing - Stop publishing location to beacons with consecutive errors (#8194).
  • Live location sharing: allow retry when stop sharing fails (#8193).
  • Allow voice messages to be scrubbed in the timeline (#8079). Fixes #18713.
  • Live location sharing - stop sharing to beacons in rooms you left (#8187).
  • Allow sending and thumbnailing AVIF images (#8172).
  • Live location sharing - handle geolocation errors (#8179).
  • Show voice room participants when not connected (#8136). Fixes #21513.
  • Add margins between labs sections (#8169).
  • Live location sharing - send geolocation beacon events - happy path (#8127).
  • Add support for Animated (A)PNG (#8158). Fixes #12967.
  • Don't form continuations from thread roots (#8166). Fixes #20908.
  • Improve handling of animated GIF and WEBP images (#8153). Fixes #16193 and #6684.
  • Wire up file preview for video files (#8140). Fixes #21539.
  • When showing thread, always auto-focus its composer (#8115). Fixes #21438.
  • Live location sharing - refresh beacon expiry in room (#8116).
  • Use styled mxids in member list v2 (#8110). Fixes #14825. Contributed by @SimonBrandner.
  • Delete groups (legacy communities system) (#8027). Fixes #17532.
  • Add a prototype of voice rooms in labs (#8084). Fixes #3546.

🐛 Bug Fixes

  • Avoid flashing the Jitsi prejoin screen at the user before skipping it (#21665).
  • Fix editing <ol> tags with a non-1 start attribute (#8211). Fixes #21625.
  • Fix URL previews being enabled when room first created (#8227). Fixes #21659.
  • Don't use m.call for Jitsi video rooms (#8223).
  • Scale emoji with size of surrounding text (#8224).
  • Make "Jump to date" translatable (#8218).
  • Normalize call buttons (#8129). Fixes #21493. Contributed by @luixxiul.
  • Show room preview bar with maximised widgets (#8180). Fixes #21542.
  • Update more strings to not wrongly mention room when it is/could be a space (#7722). Fixes #20243 and #20910.
  • Fix issue with redacting via edit composer flow causing stuck editStates (#8184).
  • Fix some image/video scroll jumps (#8182).
  • Fix "react error on share dialog" (#8170). Contributed by @yaya-usman.
  • Fix disambiguated profile in threads in bubble layout (#8168). Fixes #21570. Contributed by @SimonBrandner.
  • Responsive BetaCard on Labs (#8154). Fixes #21554. Contributed by @luixxiul.
  • Display button as inline in room directory dialog (#8164). Fixes #21567. Contributed by @luixxiul.
  • Null guard TimelinePanel unmount edge (#8171).
  • Fix beta pill label breaking (#8162). Fixes #21566. Contributed by @luixxiul.
  • Strip relations when forwarding (#7929). Fixes #19769, #18067 #21015 and #10924.
  • Don't try (and fail) to show replies for redacted events (#8141). Fixes #21435.
  • Fix 3pid member info for space member list (#8128). Fixes #21534.
  • Set max-width to user context menu (#8089). Fixes #21486. Contributed by @luixxiul.
  • Fix issue with falsey hrefs being sent in events (#8113). Fixes #21417.
  • Make video sizing consistent with images (#8102). Fixes #20072.

Changes in [1.10.9-rc.4](https://github.com/vector-im/element-web/releases/tag/v1.10.9-rc.4) (2022-04-11)

Changes in [1.10.9-rc.3](https://github.com/vector-im/element-web/releases/tag/v1.10.9-rc.3) (2022-04-08)

Changes in [1.10.9-rc.2](https://github.com/vector-im/element-web/releases/tag/v1.10.9-rc.2) (2022-04-06)

Changes in [1.10.9-rc.1](https://github.com/vector-im/element-web/releases/tag/v1.10.9-rc.1) (2022-04-05)

✨ Features

  • Release threads as a beta feature (#8081). Fixes #21351.
  • More video rooms design updates (#8222).
  • Update video rooms to new design specs (#8207). Fixes #21515, #21516 #21519 and #21526.
  • Live Location Sharing - left panel warning with error (#8201).
  • Live location sharing - Stop publishing location to beacons with consecutive errors (#8194).
  • Live location sharing: allow retry when stop sharing fails (#8193).
  • Allow voice messages to be scrubbed in the timeline (#8079). Fixes #18713.
  • Live location sharing - stop sharing to beacons in rooms you left (#8187).
  • Allow sending and thumbnailing AVIF images (#8172).
  • Live location sharing - handle geolocation errors (#8179).
  • Show voice room participants when not connected (#8136). Fixes #21513.
  • Add margins between labs sections (#8169).
  • Live location sharing - send geolocation beacon events - happy path (#8127).
  • Add support for Animated (A)PNG (#8158). Fixes #12967.
  • Don't form continuations from thread roots (#8166). Fixes #20908.
  • Improve handling of animated GIF and WEBP images (#8153). Fixes #16193 and #6684.
  • Wire up file preview for video files (#8140). Fixes #21539.
  • When showing thread, always auto-focus its composer (#8115). Fixes #21438.
  • Live location sharing - refresh beacon expiry in room (#8116).
  • Use styled mxids in member list v2 (#8110). Fixes #14825. Contributed by @SimonBrandner.
  • Delete groups (legacy communities system) (#8027). Fixes #17532.
  • Add a prototype of voice rooms in labs (#8084). Fixes #3546.

🐛 Bug Fixes

  • Fix URL previews being enabled when room first created (#8227). Fixes #21659.
  • Don't use m.call for Jitsi video rooms (#8223).
  • Scale emoji with size of surrounding text (#8224).
  • Make "Jump to date" translatable (#8218).
  • Normalize call buttons (#8129). Fixes #21493. Contributed by @luixxiul.
  • Fix editing
      tags with a non-1 start attribute (#8211). Fixes #21625.
    1. Show room preview bar with maximised widgets (#8180). Fixes #21542.
    2. Update more strings to not wrongly mention room when it is/could be a space (#7722). Fixes #20243 and #20910.
    3. Fix issue with redacting via edit composer flow causing stuck editStates (#8184).
    4. Fix some image/video scroll jumps (#8182).
    5. Fix "react error on share dialog" (#8170). Contributed by @yaya-usman.
    6. Fix disambiguated profile in threads in bubble layout (#8168). Fixes #21570. Contributed by @SimonBrandner.
    7. Responsive BetaCard on Labs (#8154). Fixes #21554. Contributed by @luixxiul.
    8. Display button as inline in room directory dialog (#8164). Fixes #21567. Contributed by @luixxiul.
    9. Null guard TimelinePanel unmount edge (#8171).
    10. Fix beta pill label breaking (#8162). Fixes #21566. Contributed by @luixxiul.
    11. Strip relations when forwarding (#7929). Fixes #19769, #18067 #21015 and #10924.
    12. Don't try (and fail) to show replies for redacted events (#8141). Fixes #21435.
    13. Fix 3pid member info for space member list (#8128). Fixes #21534.
    14. Set max-width to user context menu (#8089). Fixes #21486. Contributed by @luixxiul.
    15. Fix issue with falsey hrefs being sent in events (#8113). Fixes #21417.
    16. Make video sizing consistent with images (#8102). Fixes #20072.

Changes in [1.10.8-rc.1](https://github.com/vector-im/element-web/releases/tag/v1.10.8-rc.1) (2022-03-22)

✨ Features

  • Live location sharing: live share warning in room (#8100).
  • Add simple live share warning (#8066).
  • extract reusable styled live beacon icon (#8103).
  • Don't restore MemberInfo from RightPanel history when viewing a room (#8090). Fixes #21487.
  • Allow sending files as replies as per MSC3676 (#8020). Fixes #7156.
  • kill beacons on expiry (#8075).
  • enable geolocation behaviour in location picker for live share type (#8068).
  • Improve formatting features in the editor (#7104). Fixes #19501. Contributed by @alexanderstephan.
  • Support MSC3026 busy presence (#8043).
  • Show displayname in non-narrow thread summeries (#8036). Fixes #19646.
  • Tweak search dialog based on new designs (#7980). Fixes #21285 and #21289.
  • fallback to event text in location body when map unavailable (#7982). Fixes #20655.
  • Send pin drop location share events (#7967).

🐛 Bug Fixes

  • fix quicktime video thumbnailing (#8108). Fixes #21505.
  • Fix scroll behaviour in space panel (#8111). Fixes #21467.
  • Fix emoting with emoji or pills (#8105). Fixes #21497.
  • Remove padding of InviteDialog & fix visual regression (#8076). Fixes #20631. Contributed by @luixxiul.
  • Fixes mx_MLocationBody_markerBorder (#8069). Fixes #21444. Contributed by @luixxiul.
  • Make margin and padding of mx_InviteDialog_other consistent (#8063). Fixes #20631. Contributed by @luixxiul.
  • Fix freeze/crash when 1:1 calling (#8057). Fixes #21181.
  • Don't assume that widget IDs are unique (#8052). Fixes #21399.
  • Fix the header of Space landing page (#8048). Fixes #21402. Contributed by @luixxiul.
  • Fix buttons alignment of Space list header (#8047). Fixes #21401. Contributed by @luixxiul.
  • Fix null-guarding regression around reply_to_event dispatch (#8039).
  • Fix clicking on copy link to thread wrongly opening thread (#8038). Fixes #20653.
  • Fix regression around replying to search results (#8035). Fixes #21389.
  • Share shared history keys in the background (#8031). Fixes #21192.
  • Paginate responses to pinned polls (#8025). Fixes #21382.
  • Fix incorrect usage of unstable variant of is_falling_back (#8016).
  • Fix issues with ThreadSummary in msc-enabled mode (#8018). Fixes matrix-org/element-web-rageshakes#11401 and matrix-org/element-web-rageshakes#11400.
  • Fix alignment of polls within threads (#8017). Fixes #21235.
  • Fix issues with thread summaries being wrong or stale (#8015). Fixes #21363 and #21204.
  • Fix button border color of LeaveSpaceDialog (#8010). Fixes #21365. Contributed by @luixxiul.
  • Fix room list scroll jumps (#7991). Fixes #19322.
  • Fix a variety of issues with HTML → Markdown conversion (#8004). Fixes #10648, #20718, #10722, #10389, #17610 #9984 and #20140.
  • Wrap EventTile rather than its children in an error boundary (#7945).
  • Normalized shortcut formatting for quote expansion control (#7995). Fixes #19685. Contributed by @Sinharitik589.
  • Fix buttons and text layout on Security Key dialog (#7996). Fixes #21330. Contributed by @luixxiul.
  • Fix formatting not being applied after links (#7990). Fixes #20091.

Changes in [1.10.7](https://github.com/vector-im/element-web/releases/tag/v1.10.7) (2022-03-15)

🔒 SECURITY FIXES

  • Fix a bug where URL previews could be enabled in the left-panel when they
    should not have been.

✨ Features

  • Add a config.json option to skip the built-in Jitsi welcome screen (#21190).
  • Add unexposed account setting for hiding poll creation (#7972).
  • Allow pinning polls (#7922). Fixes #20152.
  • Make trailing : into a setting (#6711). Fixes #16682. Contributed by @SimonBrandner.
  • Location sharing > back button (#7958).
  • use LocationAssetType (#7965).
  • Location share type UI (#7924).
  • Add a few more UIComponent flags, and ensure they are used in existing code (#7937).
  • Add support for overriding strings in the app (#7886).
  • Add support for redirecting to external pages after logout (#7905).
  • Expose redaction power level in room settings (#7599). Fixes #20590. Contributed by @SimonBrandner.
  • Update and expand ways to access pinned messages (#7906). Fixes #21209 and #21211.
  • Add slash command to switch to a room's virtual room (#7839).

🐛 Bug Fixes

  • Remove Lojban translation (#21302).
  • Merge pull request from GHSA-qmf4-7w7j-vf23 (#8059).
  • Add another null guard for member (#7984). Fixes #21319.
  • Fix room account settings (#7999).
  • Fix missing summary text for pinned message changes (#7989). Fixes #19823.
  • Pass room to getRoomTombstone to avoid racing with setState (#7986).
  • Hide composer and call buttons when the room is tombstoned (#7975). Fixes #21286.
  • Fix bad ternary statement in autocomplete user pill insertions (#7977). Fixes #21307.
  • Fix sending locations into threads and fix i18n (#7943). Fixes #21267.
  • Fix location map attribution rendering over message action bar (#7974). Fixes #21297.
  • Fix wrongly asserting that PushRule::conditions is non-null (#7973). Fixes #21305.
  • Fix account & room settings race condition (#7953). Fixes #21163.
  • Fix bug with some space selections not being applied (#7971). Fixes #21290.
  • Revert "replace all require(.svg) with esm import" (#7969). Fixes #21293.
  • Hide unpinnable pinned messages in more cases (#7921).
  • Fix room list being laggy while scrolling 🐌 (#7939). Fixes #21262.
  • Make pinned messages more reliably reflect edits (#7920). Fixes #17098.
  • Improve accessibility of the BetaPill (#7949). Fixes #21255.
  • Autofocus correct composer after sending reaction (#7950). Fixes #21273.
  • Consider polls as message events for rendering redactions (#7944). Fixes #21125.
  • Prevent event tiles being shrunk/collapsed by flexbox (#7942). Fixes #21269.
  • Fix ExportDialog title on export cancellation (#7936). Fixes #21260. Contributed by @luixxiul.
  • Mandate use of js-sdk/src/matrix import over js-sdk/src (#7933). Fixes #21253.
  • Fix backspace not working in the invite dialog (#7931). Fixes #21249. Contributed by @SimonBrandner.
  • Fix right panel soft crashes due to missing room prop (#7923). Fixes #21243.
  • fix color of location share caret (#7917).
  • Wrap all EventTiles with a TileErrorBoundary and guard parsePermalink (#7916). Fixes #21216.
  • Fix changing space sometimes bouncing to the wrong space (#7910). Fixes #20425.
  • Ensure EventListSummary key does not change during backpagination (#7915). Fixes #9192.
  • Fix positioning of the thread context menu (#7918). Fixes #21236.
  • Inject sender into pinned messages (#7904). Fixes #20314.
  • Tweak info message padding in right panel timeline (#7901). Fixes #21212.
  • Fix another freeze on room switch (#7900). Fixes #21127.
  • Fix out of memory error when failing to acquire location (#7902). Fixes #21213.
  • Fix edge case in context menu chevron positioning (#7899).
  • Fix composer format buttons on WebKit (#7898). Fixes #20868.
  • manage voicerecording state when deleting or sending a voice message (#7896). Fixes #21151.
  • Fix bug with useRoomHierarchy tight-looping loadMore on error (#7893).
  • Fix upload button & shortcut not working for narrow composer mode (#7894). Fixes #21175 and #21142.
  • Fix emoji insertion in thread composer going to the main composer (#7895). Fixes #21202.
  • Try harder to keep context menus inside the window (#7863). Fixes #17527 and #18377.
  • Fix edge case around event list summary layout (#7891). Fixes #21180.
  • Fix event list summary 1 hidden message pluralisation (#7890). Fixes #21196.
  • Fix vanishing recently viewed menu (#7887). Fixes #20827.
  • Fix freeze on room switch (#7884). Fixes #21127.
  • Check 'useSystemTheme' in quick settings theme switcher (#7809). Fixes #21061.
  • Fix 'my threads' filtering to include participated threads (#7882). Fixes #20877.
  • Remove log line to try to fix freeze on answering VoIP call (#7883).
  • Support social login & password on soft logout page (#7879). Fixes #21099.
  • Fix missing padding on server picker (#7864).
  • Throttle RoomState.members handlers (#7876). Fixes #21127.
  • Only show joined/invited in search dialog (#7875). Fixes #21161.
  • Don't pillify code blocks (#7861). Fixes #20851 and #18687.
  • Fix keyboard shortcut icons on macOS (#7869).

Changes in [1.10.7-rc.1](https://github.com/vector-im/element-web/releases/tag/v1.10.7-rc.1) (2022-03-08)

✨ Features

  • Add a config.json option to skip the built-in Jitsi welcome screen (#21190).
  • Add unexposed account setting for hiding poll creation (#7972).
  • Allow pinning polls (#7922). Fixes #20152.
  • Make trailing : into a setting (#6711). Fixes #16682. Contributed by @SimonBrandner.
  • Location sharing > back button (#7958).
  • use LocationAssetType (#7965).
  • Location share type UI (#7924).
  • Add a few more UIComponent flags, and ensure they are used in existing code (#7937).
  • Add support for overriding strings in the app (#7886).
  • Add support for redirecting to external pages after logout (#7905).
  • Expose redaction power level in room settings (#7599). Fixes #20590. Contributed by @SimonBrandner.
  • Update and expand ways to access pinned messages (#7906). Fixes #21209 and #21211.
  • Add slash command to switch to a room's virtual room (#7839).

🐛 Bug Fixes

  • Remove Lojban translation (#21302).
  • Add another null guard for member (#7984). Fixes #21319.
  • Fix room account settings (#7999).
  • Fix missing summary text for pinned message changes (#7989). Fixes #19823.
  • Pass room to getRoomTombstone to avoid racing with setState (#7986).
  • Hide composer and call buttons when the room is tombstoned (#7975). Fixes #21286.
  • Fix bad ternary statement in autocomplete user pill insertions (#7977). Fixes #21307.
  • Fix sending locations into threads and fix i18n (#7943). Fixes #21267.
  • Fix location map attribution rendering over message action bar (#7974). Fixes #21297.
  • Fix wrongly asserting that PushRule::conditions is non-null (#7973). Fixes #21305.
  • Fix account & room settings race condition (#7953). Fixes #21163.
  • Fix bug with some space selections not being applied (#7971). Fixes #21290.
  • Revert "replace all require(.svg) with esm import" (#7969). Fixes #21293.
  • Hide unpinnable pinned messages in more cases (#7921).
  • Fix room list being laggy while scrolling 🐌 (#7939). Fixes #21262.
  • Make pinned messages more reliably reflect edits (#7920). Fixes #17098.
  • Improve accessibility of the BetaPill (#7949). Fixes #21255.
  • Autofocus correct composer after sending reaction (#7950). Fixes #21273.
  • Consider polls as message events for rendering redactions (#7944). Fixes #21125.
  • Prevent event tiles being shrunk/collapsed by flexbox (#7942). Fixes #21269.
  • Fix ExportDialog title on export cancellation (#7936). Fixes #21260. Contributed by @luixxiul.
  • Mandate use of js-sdk/src/matrix import over js-sdk/src (#7933). Fixes #21253.
  • Fix backspace not working in the invite dialog (#7931). Fixes #21249. Contributed by @SimonBrandner.
  • Fix right panel soft crashes due to missing room prop (#7923). Fixes #21243.
  • fix color of location share caret (#7917).
  • Wrap all EventTiles with a TileErrorBoundary and guard parsePermalink (#7916). Fixes #21216.
  • Fix changing space sometimes bouncing to the wrong space (#7910). Fixes #20425.
  • Ensure EventListSummary key does not change during backpagination (#7915). Fixes #9192.
  • Fix positioning of the thread context menu (#7918). Fixes #21236.
  • Inject sender into pinned messages (#7904). Fixes #20314.
  • Tweak info message padding in right panel timeline (#7901). Fixes #21212.
  • Fix another freeze on room switch (#7900). Fixes #21127.
  • Fix out of memory error when failing to acquire location (#7902). Fixes #21213.
  • Fix edge case in context menu chevron positioning (#7899).
  • Fix composer format buttons on WebKit (#7898). Fixes #20868.
  • manage voicerecording state when deleting or sending a voice message (#7896). Fixes #21151.
  • Fix bug with useRoomHierarchy tight-looping loadMore on error (#7893).
  • Fix upload button & shortcut not working for narrow composer mode (#7894). Fixes #21175 and #21142.
  • Fix emoji insertion in thread composer going to the main composer (#7895). Fixes #21202.
  • Try harder to keep context menus inside the window (#7863). Fixes #17527 and #18377.
  • Fix edge case around event list summary layout (#7891). Fixes #21180.
  • Fix event list summary 1 hidden message pluralisation (#7890). Fixes #21196.
  • Fix vanishing recently viewed menu (#7887). Fixes #20827.
  • Fix freeze on room switch (#7884). Fixes #21127.
  • Check 'useSystemTheme' in quick settings theme switcher (#7809). Fixes #21061.
  • Fix 'my threads' filtering to include participated threads (#7882). Fixes #20877.
  • Remove log line to try to fix freeze on answering VoIP call (#7883).
  • Support social login & password on soft logout page (#7879). Fixes #21099.
  • Fix missing padding on server picker (#7864).
  • Throttle RoomState.members handlers (#7876). Fixes #21127.
  • Only show joined/invited in search dialog (#7875). Fixes #21161.
  • Don't pillify code blocks (#7861). Fixes #20851 and #18687.
  • Fix keyboard shortcut icons on macOS (#7869).

Changes in [1.10.6](https://github.com/vector-im/element-web/releases/tag/v1.10.6) (2022-03-01)

🐛 Bug Fixes

  • Fix some crashes in the right panel

Changes in [1.10.5](https://github.com/vector-im/element-web/releases/tag/v1.10.5) (2022-02-28)

🌐 Translations

  • This release contains a significant update to the Japanese translations, contributed by Suguru Hirahara (@luixxiul). ありがとうございます!

✨ Features

  • Support "closed" polls whose votes are not visible until they are ended (#7842).
  • Focus trap in poll creation dialog (#7847). Fixes #20281.
  • Add labs flag: Show only current profile on historical messages (#7815).
  • Keep unsent voice messages in memory until they are deleted or sent (#7840). Fixes #17979.
  • A link to #/dm in a custom home.html will open the "Direct Messages" dialog. (#7783). Contributed by @johannes-krude.
  • set icon-button-color to be configurable via quaternary-content variable (#7725). Fixes #20925. Contributed by @acxz.
  • Allow editing polls (#7806).
  • Abstract spotlight to allow non-room results too (#7804). Fixes #20968, matrix-org/element-web-rageshakes#10766, matrix-org/element-web-rageshakes#10777, matrix-org/element-web-rageshakes#10767 matrix-org/element-web-rageshakes#10760 and matrix-org/element-web-rageshakes#10752.
  • Display '(edited)' next to edited polls (#7789).
  • Use the resize observer polyfill consistently (#7796). Fixes matrix-org/element-web-rageshakes#10700.
  • Consolidate, simplify and improve copied tooltips (#7799). Fixes #21069.
  • Suggest @room when @channel, @everyone, or @here is typed in composer (#7737). Fixes #20972. Contributed by @aaronraimist.
  • Add customisation point to disable space creation (#7766).
  • Consolidate RedactionGrouper and HiddenEventGrouper into MELS (#7739). Fixes #20958.
  • Unify widget header actions with those in right panel (#7734).
  • Improve new search dialog context text for exactly 2 parent spaces (#7761).

🐛 Bug Fixes

  • Fix command key missing in keyboard shortcuts tab (#21102). Contributed by @SimonBrandner.
  • [Release] Tweak info message padding in right panel timeline (#7909).
  • [Release] Fix edge case around event list summary layout (#7892).
  • Wire up CallEventGroupers for Search Results (#7866). Fixes #21150.
  • Fix edge case around event list summary layout (#7867). Fixes #21153.
  • Fix misalignment with Event List Summaries (#7865). Fixes #21149.
  • Fix non-customizable keybindings not working as expected (#7855). Fixes #21136 and matrix-org/element-web-rageshakes#10830.
  • Fix accessibility around the room list treeview and new search beta (#7856). Fixes matrix-org/element-web-rageshakes#10873.
  • Inhibit tooltip on timeline pill avatars, the whole pill has its own (#7854). Fixes #21135.
  • Fix virtual / native room mapping on call transfers (#7848).
  • Fix ScrollPanel data-scrollbar not responding to window resizing (#7841). Fixes #20594.
  • add cursor: pointer to actionable poll options (#7826). Fixes #21033.
  • Tear down AppTile using lifecycle tracking (#7833). Fixes #21025.
  • Fix layout inconsistencies with the room search minimized button (#7824). Fixes #21106.
  • Fix space panel notification badge behaviour and metrics (#7823). Fixes #21092.
  • Fix left panel widgets causing app crashes (again) (#7814).
  • Fix right panel data flow (#7811). Fixes #20929.
  • set mask-size for icons (#7812). Fixes #21047.
  • Fix room create tile not showing up with hidden events shown (#7810). Fixes #20893.
  • Fix delayed badge update for mentions in encrypted rooms (#7813). Fixes #20859.
  • Fix add existing space not showing any spaces (#7801). Fixes #21087. Contributed by @c-cal.
  • Fix edge cases around event list summaries with hidden events and redactions (#7797). Fixes #21030 #21050 and #21055.
  • Improve styling of edge case devtools state keys (#7794). Fixes #21056.
  • Don't scroll to bottom when executing non-message slash commands (#7793). Fixes #21065.
  • Fix cutout misalignment on some decorated room avatars (#7784). Fixes #21038.
  • Fix desktop notifications for invites showing user IDs instead of displaynames (#7780). Fixes #21022. Contributed by @c-cal.
  • Fix bad pluralisation on event list summary hidden message handling (#7778).
  • Properly recurse subspaces for leave space dialog options (#7775). Fixes #20949 and #21012.
  • Fix translation for keyboard shortcut displaynames (#7758). Fixes #20992. Contributed by @c-cal.
  • Fix space member list opening with back button (#7773). Fixes #21009. Contributed by @c-cal.
  • Fix sort order for facepiles which was exactly reverse (#7771).
  • Fix state events being wrongly hidden when redacted (#7768). Fixes #20959.
  • Event List Summary guard against missing event senders (#7767). Fixes #21004.
  • Fix all settings button opening sidebar settings tab (#7765). Fixes #20998. Contributed by @c-cal.
  • Fix theme selector dropdown overflow (#7764). Fixes #20996. Contributed by @c-cal.
  • Fix widget and mjolnir state events showing with mxid not name (#7760). Fixes #20986.
  • Fix space member list not opening (#7747). Fixes #20982. Contributed by @c-cal.
  • Handle highlight notifications in timeline card button (#7762). Fixes #20987. Contributed by @SimonBrandner.
  • Fix add existing space not showing any spaces (#7751).
  • Inhibit Room List keyboard pass-thru when the search beta is enabled (#7752). Fixes #20984.
  • Add unread notification dot to timeline card button (#7749). Fixes #20946. Contributed by @SimonBrandner.

Changes in [1.10.5-rc.1](https://github.com/vector-im/element-web/releases/tag/v1.10.5-rc.1) (2022-02-22)

🌐 Translations

  • This release contains a significant update to the Japanese translations, contributed by Suguru Hirahara (@luixxiul). ありがとうございます!

✨ Features

  • Support "closed" polls whose votes are not visible until they are ended (#7842).
  • Focus trap in poll creation dialog (#7847). Fixes #20281.
  • Add labs flag: Show only current profile on historical messages (#7815).
  • Keep unsent voice messages in memory until they are deleted or sent (#7840). Fixes #17979.
  • A link to #/dm in a custom home.html will open the "Direct Messages" dialog. (#7783). Contributed by @johannes-krude.
  • set icon-button-color to be configurable via quaternary-content variable (#7725). Fixes #20925. Contributed by @acxz.
  • Allow editing polls (#7806).
  • Abstract spotlight to allow non-room results too (#7804). Fixes #20968, matrix-org/element-web-rageshakes#10766, matrix-org/element-web-rageshakes#10777, matrix-org/element-web-rageshakes#10767 matrix-org/element-web-rageshakes#10760 and matrix-org/element-web-rageshakes#10752.
  • Display '(edited)' next to edited polls (#7789).
  • Use the resize observer polyfill consistently (#7796). Fixes matrix-org/element-web-rageshakes#10700.
  • Consolidate, simplify and improve copied tooltips (#7799). Fixes #21069.
  • Suggest @room when @channel, @everyone, or @here is typed in composer (#7737). Fixes #20972. Contributed by @aaronraimist.
  • Add customisation point to disable space creation (#7766).
  • Consolidate RedactionGrouper and HiddenEventGrouper into MELS (#7739). Fixes #20958.
  • Unify widget header actions with those in right panel (#7734).
  • Improve new search dialog context text for exactly 2 parent spaces (#7761).

🐛 Bug Fixes

  • Fix command key missing in keyboard shortcuts tab (#21102). Contributed by @SimonBrandner.
  • Wire up CallEventGroupers for Search Results (#7866). Fixes #21150.
  • Fix edge case around event list summary layout (#7867). Fixes #21153.
  • Fix misalignment with Event List Summaries (#7865). Fixes #21149.
  • Fix non-customizable keybindings not working as expected (#7855). Fixes #21136 and matrix-org/element-web-rageshakes#10830.
  • Fix accessibility around the room list treeview and new search beta (#7856). Fixes matrix-org/element-web-rageshakes#10873.
  • Inhibit tooltip on timeline pill avatars, the whole pill has its own (#7854). Fixes #21135.
  • Fix virtual / native room mapping on call transfers (#7848).
  • Fix ScrollPanel data-scrollbar not responding to window resizing (#7841). Fixes #20594.
  • add cursor: pointer to actionable poll options (#7826). Fixes #21033.
  • Tear down AppTile using lifecycle tracking (#7833). Fixes #21025.
  • Fix layout inconsistencies with the room search minimized button (#7824). Fixes #21106.
  • Fix space panel notification badge behaviour and metrics (#7823). Fixes #21092.
  • Fix left panel widgets causing app crashes (again) (#7814).
  • Fix right panel data flow (#7811). Fixes #20929.
  • set mask-size for icons (#7812). Fixes #21047.
  • Fix room create tile not showing up with hidden events shown (#7810). Fixes #20893.
  • Fix delayed badge update for mentions in encrypted rooms (#7813). Fixes #20859.
  • Fix add existing space not showing any spaces (#7801). Fixes #21087. Contributed by @c-cal.
  • Fix edge cases around event list summaries with hidden events and redactions (#7797). Fixes #21030 #21050 and #21055.
  • Improve styling of edge case devtools state keys (#7794). Fixes #21056.
  • Don't scroll to bottom when executing non-message slash commands (#7793). Fixes #21065.
  • Fix cutout misalignment on some decorated room avatars (#7784). Fixes #21038.
  • Fix desktop notifications for invites showing user IDs instead of displaynames (#7780). Fixes #21022. Contributed by @c-cal.
  • Fix bad pluralisation on event list summary hidden message handling (#7778).
  • Properly recurse subspaces for leave space dialog options (#7775). Fixes #20949 and #21012.
  • Fix translation for keyboard shortcut displaynames (#7758). Fixes #20992. Contributed by @c-cal.
  • Fix space member list opening with back button (#7773). Fixes #21009. Contributed by @c-cal.
  • Fix sort order for facepiles which was exactly reverse (#7771).
  • Fix state events being wrongly hidden when redacted (#7768). Fixes #20959.
  • Event List Summary guard against missing event senders (#7767). Fixes #21004.
  • Fix all settings button opening sidebar settings tab (#7765). Fixes #20998. Contributed by @c-cal.
  • Fix theme selector dropdown overflow (#7764). Fixes #20996. Contributed by @c-cal.
  • Fix widget and mjolnir state events showing with mxid not name (#7760). Fixes #20986.
  • Fix space member list not opening (#7747). Fixes #20982. Contributed by @c-cal.
  • Handle highlight notifications in timeline card button (#7762). Fixes #20987. Contributed by @SimonBrandner.
  • Fix add existing space not showing any spaces (#7751).
  • Inhibit Room List keyboard pass-thru when the search beta is enabled (#7752). Fixes #20984.
  • Add unread notification dot to timeline card button (#7749). Fixes #20946. Contributed by @SimonBrandner.

Changes in [1.10.4](https://github.com/vector-im/element-web/releases/tag/v1.10.4) (2022-02-17)

🐛 Bug Fixes

  • Fix bug where badge colour on encrypted rooms may not be correct until anothe rmessage is sent

Changes in [1.10.3](https://github.com/vector-im/element-web/releases/tag/v1.10.3) (2022-02-14)

  • Add map tile URL for location sharing maps to sample config (and element.io release app config)

Changes in [1.10.2](https://github.com/vector-im/element-web/releases/tag/v1.10.2) (2022-02-14)

✨ Features

  • Support a config option to change the default device name (#20790).
  • Capitalize "Privacy" in UserMenu (#7738). Contributed by @aaronraimist.
  • Move new search experience to a Beta (#7718). Fixes vector-im/element-meta#139 #20618 and #20339.
  • Auto select "Other homeserver" when user press "Edit" in homeserver field (#7337). Fixes #20125. Contributed by @SimonBrandner.
  • Add unread badges and avatar decorations to spotlight search (#7696). Fixes #20821.
  • Enable location sharing (#7703).
  • Simplify Composer buttons (#7678).
  • Add a warning to the console to discourage attacks and encourage contributing (#7673). Fixes #2803. Contributed by @SimonBrandner.
  • Don't show replaced calls in the timeline (#7452). Contributed by @SimonBrandner.
  • Tweak /addwidget widget names (#7681).
  • Chat export parameter customisation (#7647).
  • Put call on hold when transfer dialog is opened (#7669).
  • Share e2ee keys when using /invite SlashCommand (#7655). Fixes #20778 and #16982.
  • Tweak spotlight roving behaviour to reset when changing query (#7656). Fixes #20537 #20612 and #20184.
  • Look up tile server info in homeserver's .well-known area (#7623).
  • Add grouper for hidden events (#7649).
  • The keyboard shortcut is control (or cmd) shift h. (#7584). Contributed by @UwUnyaa.

🐛 Bug Fixes

  • [Release] Fix cutout misalignment on some decorated room avatars (#7785).
  • [Release] Fix add existing space not showing any spaces (#7756).
  • [Release] Inhibit Room List keyboard pass-thru when the search beta is enabled (#7754).
  • [Release] Fix space member list not opening (#7755).
  • Null-guard ELS from null summaryMembers (#7744). Fixes #20807.
  • Improve responsiveness of the layout switcher (#7736).
  • Tweak timeline card layout (#7743). Fixes #20846.
  • Ensure location bodies have a width in bubbles (#7742). Fixes #20916.
  • Tune aria-live regions around clocks/timers (#7735). Fixes #20967.
  • Fix instances of decorated room avatar wrongly having their own tabIndex (#7730).
  • Remove weird padding on stickers (#6271). Fixes #17787. Contributed by @SimonBrandner.
  • Fix width issue of the composer overflow menu items (#7731). Fixes #20898.
  • Properly handle persistent widgets when room is left (#7724). Fixes #20901.
  • Null guard space hierarchy (#7729). Fixes matrix-org/element-web-rageshakes#10433.
  • Fix add existing rooms button (#7728). Fixes #20924. Contributed by @SimonBrandner.
  • Truncate long server names on login/register screen (#7702). Fixes #18452.
  • Update PollCreateDialog-test to snapshot the html and not react tree (#7712).
  • Fix creating polls outside of threads (#7711). Fixes #20882.
  • Open native room when clicking notification from a virtual room (#7709).
  • Fix relative link handling in Element Desktop (#7708). Fixes #20783.
  • Reuse CopyableText component in all places it can be (#7701). Fixes #20855.
  • Fit location into the width of the container (#7705). Fixes #20861.
  • Make Spotlight Dialog roving reset more stable (#7698). Fixes #20826.
  • Fix incorrect sizing of DecoratedRoomAvatar in RoomHeader (#7697). Fixes #20090.
  • Use a more correct test for emoji (#7685). Fixes #20824. Contributed by @robintown.
  • Fix vertical spacing in compact <ContextMenu> (#7684). Fixes #20801.
  • Fix the sticker picker (#7692). Fixes #20797.
  • Fix publishing address wrongly demanding the alias be available (#7690). Fixes #12013 and #20833.
  • Prevent MemberAvatar soft-crashing when rendered with null member prop (#7691). Fixes #20714.
  • Ensure UserInfo can be rendered without a room (#7687). Fixes #20830.
  • Make polls fill column width in bubbles layout (#7661). Fixes #20712.
  • Add a background to expanded nick name in IRC layout to make it readable. (#7652). Fixes #20757. Contributed by @UwUnyaa.
  • Fix accessibility and consistency of MessageComposerButtons (#7679). Fixes #20814.
  • Don't show shield next to deleted messages (#7671). Fixes #20475. Contributed by @SimonBrandner.
  • Fix font size of spaces between big emoji (#7675). Contributed by @robintown.
  • Fix shift-enter repeating last character (#7665). Fixes #17215. Contributed by @SimonBrandner.
  • Remove Unpin option from maximised widget context menu (#7657).
  • Fix new call event grouper implementation for encrypted rooms (#7654).
  • Fix issue with tile error boundaries collapsing in bubbles layout (#7653).
  • Fix emojis getting cropped in irc & bubble layouts by anti-zalgo (#7637). Fixes #20744.
  • Fix space panel edge gradient not applying on load (#7644). Fixes #20756.
  • Fix search results view for layouts other than Group/Modern (#7648). Fixes #20745.

Changes in [1.10.2-rc.2](https://github.com/vector-im/element-web/releases/tag/v1.10.2-rc.2) (2022-02-09)

🐛 Bug Fixes

  • [Release] Fix add existing space not showing any spaces (#7756).
  • [Release] Inhibit Room List keyboard pass-thru when the search beta is enabled (#7754).
  • [Release] Fix space member list not opening (#7755).

Changes in [1.10.2-rc.1](https://github.com/vector-im/element-web/releases/tag/v1.10.2-rc.1) (2022-02-08)

✨ Features

  • Support a config option to change the default device name (#20790).
  • Move new search experience to a Beta (#7718). Fixes vector-im/element-meta#139 #20618 and #20339.
  • Capitalize "Privacy" in UserMenu (#7738). Contributed by @aaronraimist.
  • Auto select "Other homeserver" when user press "Edit" in homeserver field (#7337). Fixes #20125. Contributed by @SimonBrandner.
  • Add unread badges and avatar decorations to spotlight search (#7696). Fixes #20821.
  • Enable location sharing (#7703).
  • Simplify Composer buttons (#7678).
  • Add a warning to the console to discourage attacks and encourage contributing (#7673). Fixes #2803. Contributed by @SimonBrandner.
  • Don't show replaced calls in the timeline (#7452). Contributed by @SimonBrandner.
  • Tweak /addwidget widget names (#7681).
  • Chat export parameter customisation (#7647).
  • Put call on hold when transfer dialog is opened (#7669).
  • Share e2ee keys when using /invite SlashCommand (#7655). Fixes #20778 and #16982.
  • Tweak spotlight roving behaviour to reset when changing query (#7656). Fixes #20537 #20612 and #20184.
  • Look up tile server info in homeserver's .well-known area (#7623).
  • Add grouper for hidden events (#7649).
  • The keyboard shortcut is control (or cmd) shift h. (#7584). Contributed by @UwUnyaa.

🐛 Bug Fixes

  • Null-guard ELS from null summaryMembers (#7744). Fixes #20807.
  • Improve responsiveness of the layout switcher (#7736).
  • Tweak timeline card layout (#7743). Fixes #20846.
  • Ensure location bodies have a width in bubbles (#7742). Fixes #20916.
  • Tune aria-live regions around clocks/timers (#7735). Fixes #20967.
  • Fix instances of decorated room avatar wrongly having their own tabIndex (#7730).
  • Remove weird padding on stickers (#6271). Fixes #17787. Contributed by @SimonBrandner.
  • Fix width issue of the composer overflow menu items (#7731). Fixes #20898.
  • Properly handle persistent widgets when room is left (#7724). Fixes #20901.
  • Null guard space hierarchy (#7729). Fixes matrix-org/element-web-rageshakes#10433.
  • Fix add existing rooms button (#7728). Fixes #20924. Contributed by @SimonBrandner.
  • Truncate long server names on login/register screen (#7702). Fixes #18452.
  • Update PollCreateDialog-test to snapshot the html and not react tree (#7712).
  • Fix creating polls outside of threads (#7711). Fixes #20882.
  • Open native room when clicking notification from a virtual room (#7709).
  • Fix relative link handling in Element Desktop (#7708). Fixes #20783.
  • Reuse CopyableText component in all places it can be (#7701). Fixes #20855.
  • Fit location into the width of the container (#7705). Fixes #20861.
  • Make Spotlight Dialog roving reset more stable (#7698). Fixes #20826.
  • Fix incorrect sizing of DecoratedRoomAvatar in RoomHeader (#7697). Fixes #20090.
  • Use a more correct test for emoji (#7685). Fixes #20824. Contributed by @robintown.
  • Fix vertical spacing in compact <ContextMenu> (#7684). Fixes #20801.
  • Fix the sticker picker (#7692). Fixes #20797.
  • Fix publishing address wrongly demanding the alias be available (#7690). Fixes #12013 and #20833.
  • Prevent MemberAvatar soft-crashing when rendered with null member prop (#7691). Fixes #20714.
  • Ensure UserInfo can be rendered without a room (#7687). Fixes #20830.
  • Make polls fill column width in bubbles layout (#7661). Fixes #20712.
  • Add a background to expanded nick name in IRC layout to make it readable. (#7652). Fixes #20757. Contributed by @UwUnyaa.
  • Fix accessibility and consistency of MessageComposerButtons (#7679). Fixes #20814.
  • Don't show shield next to deleted messages (#7671). Fixes #20475. Contributed by @SimonBrandner.
  • Fix font size of spaces between big emoji (#7675). Contributed by @robintown.
  • Fix shift-enter repeating last character (#7665). Fixes #17215. Contributed by @SimonBrandner.
  • Remove Unpin option from maximised widget context menu (#7657).
  • Fix new call event grouper implementation for encrypted rooms (#7654).
  • Fix issue with tile error boundaries collapsing in bubbles layout (#7653).
  • Fix emojis getting cropped in irc & bubble layouts by anti-zalgo (#7637). Fixes #20744.
  • Fix space panel edge gradient not applying on load (#7644). Fixes #20756.
  • Fix search results view for layouts other than Group/Modern (#7648). Fixes #20745.

Changes in [1.10.1](https://github.com/vector-im/element-web/releases/tag/v1.10.1) (2022-02-01)

🐛 Bug Fixes

  • Fix the sticker picker (#7692). Fixes vector-im/element-web#20797.
  • Ensure UserInfo can be rendered without a room (#7687). Fixes vector-im/element-web#20830.
  • Fix publishing address wrongly demanding the alias be available (#7690). Fixes vector-im/element-web#12013 and vector-im/element-web#20833.

Changes in [1.10.0](https://github.com/vector-im/element-web/releases/tag/v1.10.0) (2022-01-31)

✨ Features

  • Tweak room list header menu for when space is active (#7577). Fixes #20601.
  • Tweak light hover & active color for bubble layout (#7626). Fixes #19475.
  • De-labs Metaspaces (#7613).
  • De-labs Message Bubbles layout (#7612).
  • Add customisation point for mxid display (#7595).
  • Add labs flag for default open right panel (#7618). Fixes #20666.
  • Tweak copy for the Sidebar tab in User Settings (#7578). Fixes #20619.
  • Make widgets not reload (persistent) between center and top container (#7575). Fixes #20596. Contributed by @toger5.
  • Don't render a bubble around emotes in bubble layout (#7573). Fixes #20617.
  • Add ability to switch between voice & video in calls (#7155). Fixes #18619. Contributed by @SimonBrandner.
  • Re-renable Share option for location messages (#7596).
  • Make room ID copyable (#7600). Fixes #20675. Contributed by @SimonBrandner.
  • Improve the look of the keyboard settings tab (#7562). Contributed by @SimonBrandner.
  • Add tooltips to emoji in messages (#7592). Fixes #9911 and #20661. Contributed by @robintown.
  • Improve redundant tooltip on send button in forward dialog (#7594). Contributed by @twigleingrid.
  • Allow downloads from widgets. (#7502). Contributed by @Fox32.
  • Parse matrix-schemed URIs (#7453).
  • Show a tile at beginning of visible history (#5887). Fixes #16818 #16679 and #19888. Contributed by @robintown.
  • Enable the polls feature (#7581).
  • Display general marker on non-self location shares (#7574).
  • Improve/add notifications for location and poll events (#7552). Fixes #20561. Contributed by @SimonBrandner.
  • Upgrade linkify to v3.0 (#7282). Fixes #17133 #16825 and #5808. Contributed by @Palid.
  • Update sidebar icon from Compound (#7572). Fixes #20615.
  • Replace home icon with new one (#7571). Fixes #20606.
  • Make the Keyboard Shortcuts dialog into a settings tab (#7198). Fixes #19866. Contributed by @SimonBrandner.
  • Add setting for enabling location sharing (#7547).
  • Add a developer mode 'view source' button to crashed event tiles (#7537).
  • Replace kick terminology with Remove from chat (#7469). Fixes #9547.
  • Render events as extensible events (behind labs) (#7462).
  • Render Jitsi (and other sticky widgets) in PiP container, so it can be dragged and the "jump to room functionality" is provided (#7450). Fixes #15682. Contributed by @toger5.
  • Allow bubble layout in Thread View (#7478). Fixes #20419.
  • Make LocationPicker appearance cleaner (#7516).
  • Limit max-width for bubble layout to 1200px (#7458). Fixes #18072.
  • Improve look of call events in bubble layout (#7445). Fixes #20324. Contributed by @SimonBrandner.
  • Make files & voice memos in bubble layout match colouring (#7457). Fixes #20326.
  • Allow cancelling events whilst they are encrypting (#7483). Fixes #17726.

🐛 Bug Fixes

  • [Release] Fix left panel widgets causing app-wide crash (#7660).
  • Load light theme prior to HTML export to ensure it is present (#7643). Fixes #20276.
  • Fix soft-crash when hanging up Jitsi via PIP (#7645). Fixes #20766.
  • Fix RightPanelStore assuming isViewingRoom is false on load (#7642).
  • Correctly handle Room.timeline events which have a nullable Room (#7635). Fixes matrix-org/element-web-rageshakes#9490.
  • Translate keyboard shortcut alternate key names (#7633). Fixes #20739.
  • Fix unfocused paste handling and focus return for file uploads (#7625).
  • Changed MacOS hotkey for GoToHome view. (#7631). Contributed by @aj-ya.
  • Fix issue with the new composer EmojiPart which caused infinite loops (#7629). Fixes #20746.
  • Upgrade linkifyjs to fix schemes as domain prefixes (#7628). Fixes #20720.
  • Show bubble tile timestamps for bubble layout inside the bubble (#7622). Fixes #20562.
  • Improve taken username warning in registration for when request fails (#7621).
  • Avoid double dialog after clicking to remove a public room (#7604). Fixes #20681. Contributed by @c-cal.
  • Fix space member list right panel state (#7617). Fixes #20716.
  • Fall back to legacy analytics for guest users (#7616).
  • Always emit a space filter update when the space is actually changed (#7611). Fixes #20664.
  • Enlarge emoji in composer (#7602). Fixes #20665 #15635 and #20688. Contributed by @robintown.
  • Disable location sharing button on Desktop (#7590).
  • Make pills more natural to navigate around (#7607). Fixes #20678. Contributed by @robintown.
  • Fix excessive padding on inline images (#7605). Contributed by @robintown.
  • Prevent pills from being split by formatting actions (#7606). Contributed by @robintown.
  • Fix translation of "powerText" (#7603). Contributed by @c-cal.
  • Unhide display names when switching back to modern layout (#7601). Fixes #20676. Contributed by @robintown.
  • Fix space member list not opening (#7609). Fixes #20679. Contributed by @SimonBrandner.
  • Fix translation for the "Add room" tooltip (#7532). Contributed by @c-cal.
  • Make the close button of the location share dialog visible in high-contrast theme (#7597).
  • Cancel pending events in virtual room when call placed (#7583). Fixes #17594.
  • Fix alignment of unread badge in thread list (#7582). Fixes #20643.
  • Fix left positioned tooltips being wrong and offset by fixed value (#7551).
  • Fix MAB overlapping or overflowing in bubbles layout and threads regressions (#7569). Fixes #20403 and #20404.
  • Fix wrong icon being used for appearance tab in space preferences dialog (#7570). Fixes #20608.
  • Fix /jumptodate using wrong MSC feature flag (#7563).
  • Ensure maps show up in replies and threads, by creating unique IDs (#7568).
  • Differentiate between hover and roving focus in spotlight dialog (#7564). Fixes #20597.
  • Fix timeline jumping issues related to bubble layout (#7529). Fixes #20302.
  • Start a conference in a room with 2 people + invitee rather than a 1:1 call (#7557). Fixes #1202. Contributed by @SimonBrandner.
  • Wait for initial profile load before displaying widget (#7556).
  • Make widgets and calls span across the whole room width when using bubble layout (#7553). Fixes #20560. Contributed by @SimonBrandner.
  • Always show right panel after setting a card (#7544). Contributed by @toger5.
  • Support deserialising HR tags for editing (#7543). Fixes #20553.
  • Refresh ThreadView after React state has been updated (#7539). Fixes #20549.
  • Set initial zoom level to 1 to make zooming to location faster (#7541).
  • truncate room name on pip header (#7538).
  • Prevent enter to send edit weirdness when no change has been made (#7522). Fixes #20507.
  • Allow using room pills in slash commands (#7513). Fixes #20343.

Changes in [1.9.10-rc.2](https://github.com/vector-im/element-web/releases/tag/v1.9.10-rc.2) (2022-01-26)

🐛 Bug Fixes

  • Fix crash in settings / appearance

Changes in [1.9.10-rc.1](https://github.com/vector-im/element-web/releases/tag/v1.9.10-rc.1) (2022-01-26)

✨ Features

  • Enable posthog on app.element.io (#20539).
  • Tweak room list header menu for when space is active (#7577). Fixes #20601.
  • Tweak light hover & active color for bubble layout (#7626). Fixes #19475.
  • De-labs Metaspaces (#7613).
  • De-labs Message Bubbles layout (#7612).
  • Add customisation point for mxid display (#7595).
  • Add labs flag for default open right panel (#7618). Fixes #20666.
  • Tweak copy for the Sidebar tab in User Settings (#7578). Fixes #20619.
  • Make widgets not reload (persistent) between center and top container (#7575). Fixes #20596. Contributed by @toger5.
  • Don't render a bubble around emotes in bubble layout (#7573). Fixes #20617.
  • Add ability to switch between voice & video in calls (#7155). Fixes #18619. Contributed by @SimonBrandner.
  • Re-renable Share option for location messages (#7596).
  • Make room ID copyable (#7600). Fixes #20675. Contributed by @SimonBrandner.
  • Improve the look of the keyboard settings tab (#7562). Contributed by @SimonBrandner.
  • Add tooltips to emoji in messages (#7592). Fixes #9911 and #20661. Contributed by @robintown.
  • Improve redundant tooltip on send button in forward dialog (#7594). Contributed by @twigleingrid.
  • Allow downloads from widgets. (#7502). Contributed by @Fox32.
  • Parse matrix-schemed URIs (#7453).
  • Show a tile at beginning of visible history (#5887). Fixes #16818 #16679 and #19888. Contributed by @robintown.
  • Enable the polls feature (#7581).
  • Display general marker on non-self location shares (#7574).
  • Improve/add notifications for location and poll events (#7552). Fixes #20561. Contributed by @SimonBrandner.
  • Upgrade linkify to v3.0 (#7282). Fixes #17133 #16825 and #5808. Contributed by @Palid.
  • Update sidebar icon from Compound (#7572). Fixes #20615.
  • Replace home icon with new one (#7571). Fixes #20606.
  • Make the Keyboard Shortcuts dialog into a settings tab (#7198). Fixes #19866. Contributed by @SimonBrandner.
  • Add setting for enabling location sharing (#7547).
  • Add a developer mode 'view source' button to crashed event tiles (#7537).
  • Replace kick terminology with Remove from chat (#7469). Fixes #9547.
  • Render events as extensible events (behind labs) (#7462).
  • Render Jitsi (and other sticky widgets) in PiP container, so it can be dragged and the "jump to room functionality" is provided (#7450). Fixes #15682. Contributed by @toger5.
  • Allow bubble layout in Thread View (#7478). Fixes #20419.
  • Make LocationPicker appearance cleaner (#7516).
  • Limit max-width for bubble layout to 1200px (#7458). Fixes #18072.
  • Improve look of call events in bubble layout (#7445). Fixes #20324. Contributed by @SimonBrandner.
  • Make files & voice memos in bubble layout match colouring (#7457). Fixes #20326.
  • Allow cancelling events whilst they are encrypting (#7483). Fixes #17726.

🐛 Bug Fixes

  • Load light theme prior to HTML export to ensure it is present (#7643). Fixes #20276.
  • Fix soft-crash when hanging up Jitsi via PIP (#7645). Fixes #20766.
  • Fix RightPanelStore assuming isViewingRoom is false on load (#7642).
  • Correctly handle Room.timeline events which have a nullable Room (#7635). Fixes matrix-org/element-web-rageshakes#9490.
  • Translate keyboard shortcut alternate key names (#7633). Fixes #20739.
  • Fix unfocused paste handling and focus return for file uploads (#7625).
  • Changed MacOS hotkey for GoToHome view. (#7631). Contributed by @aj-ya.
  • Fix issue with the new composer EmojiPart which caused infinite loops (#7629). Fixes #20746.
  • Upgrade linkifyjs to fix schemes as domain prefixes (#7628). Fixes #20720.
  • Show bubble tile timestamps for bubble layout inside the bubble (#7622). Fixes #20562.
  • Improve taken username warning in registration for when request fails (#7621).
  • Avoid double dialog after clicking to remove a public room (#7604). Fixes #20681. Contributed by @c-cal.
  • Fix space member list right panel state (#7617). Fixes #20716.
  • Fall back to legacy analytics for guest users (#7616).
  • Always emit a space filter update when the space is actually changed (#7611). Fixes #20664.
  • Enlarge emoji in composer (#7602). Fixes #20665 #15635 and #20688. Contributed by @robintown.
  • Disable location sharing button on Desktop (#7590).
  • Make pills more natural to navigate around (#7607). Fixes #20678. Contributed by @robintown.
  • Fix excessive padding on inline images (#7605). Contributed by @robintown.
  • Prevent pills from being split by formatting actions (#7606). Contributed by @robintown.
  • Fix translation of "powerText" (#7603). Contributed by @c-cal.
  • Unhide display names when switching back to modern layout (#7601). Fixes #20676. Contributed by @robintown.
  • Fix space member list not opening (#7609). Fixes #20679. Contributed by @SimonBrandner.
  • Fix translation for the "Add room" tooltip (#7532). Contributed by @c-cal.
  • Make the close button of the location share dialog visible in high-contrast theme (#7597).
  • Cancel pending events in virtual room when call placed (#7583). Fixes #17594.
  • Fix alignment of unread badge in thread list (#7582). Fixes #20643.
  • Fix left positioned tooltips being wrong and offset by fixed value (#7551).
  • Fix MAB overlapping or overflowing in bubbles layout and threads regressions (#7569). Fixes #20403 and #20404.
  • Fix wrong icon being used for appearance tab in space preferences dialog (#7570). Fixes #20608.
  • Fix /jumptodate using wrong MSC feature flag (#7563).
  • Ensure maps show up in replies and threads, by creating unique IDs (#7568).
  • Differentiate between hover and roving focus in spotlight dialog (#7564). Fixes #20597.
  • Fix timeline jumping issues related to bubble layout (#7529). Fixes #20302.
  • Start a conference in a room with 2 people + invitee rather than a 1:1 call (#7557). Fixes #1202. Contributed by @SimonBrandner.
  • Wait for initial profile load before displaying widget (#7556).
  • Make widgets and calls span across the whole room width when using bubble layout (#7553). Fixes #20560. Contributed by @SimonBrandner.
  • Always show right panel after setting a card (#7544). Contributed by @toger5.
  • Support deserialising HR tags for editing (#7543). Fixes #20553.
  • Refresh ThreadView after React state has been updated (#7539). Fixes #20549.
  • Set initial zoom level to 1 to make zooming to location faster (#7541).
  • truncate room name on pip header (#7538).
  • Prevent enter to send edit weirdness when no change has been made (#7522). Fixes #20507.
  • Allow using room pills in slash commands (#7513). Fixes #20343.

Changes in [1.9.9](https://github.com/vector-im/element-web/releases/tag/v1.9.9) (2022-01-17)

✨ Features

  • Add permission dropdown for sending reactions (#7492). Fixes #20450.
  • Ship maximised widgets and remove feature flag (#7509).
  • Properly maintain aspect ratio of inline images (#7503).
  • Add zoom buttons to the location view (#7482).
  • Remove bubble from around location events (#7459). Fixes #20323.
  • Disable "Publish this room" option in invite only rooms (#7441). Fixes #6596. Contributed by @aaronraimist.
  • Give secret key field an id (#7489). Fixes #20390. Contributed by @SimonBrandner.
  • Display a tooltip when you hover over a location (#7472).
  • Open map in a dialog when it is clicked (#7465).
  • a11y - wrap notification level radios in fieldsets (#7471).
  • Wrap inputs in fieldsets in Space visibility settings (#7350).
  • History based navigation with new right panel store (#7398). Fixes #19686 #19660 and #19634.
  • Associate room alias warning with public option in settings (#7430).
  • Disable quick reactions button when no permissions (#7412). Fixes #20270.
  • Allow opening a map view in OpenStreetMap (#7428).
  • Display the user's avatar when they shared their location (#7424).
  • Remove the Forward and Share buttons for location messages only (#7423).
  • Add configuration to disable relative date markers in timeline (#7405).
  • Space preferences for whether or not you see DMs in a Space (#7250). Fixes #19529 and #19955.
  • Have LocalEchoWrapper emit updates so the app can react faster (#7358). Fixes #19749.
  • Use semantic heading on dialog component (#7383).
  • Add /jumptodate slash command (#7372). Fixes #7677.
  • Update room context menu copy (#7361). Fixes #20133.
  • Use lazy rendering in the AddExistingToSpaceDialog (#7369). Fixes #18784.
  • Tweak FacePile tooltip to include whether or not you are included (#7367). Fixes #17278.

🐛 Bug Fixes

  • Ensure group audio-only calls don't switch on the webcam on join (#20234). Fixes #20212.
  • Fix wrongly wrapping code blocks, breaking line numbers (#7507). Fixes #20316.
  • Set header buttons to no phase when right panel is closed (#7506).
  • Fix active Jitsi calls (and other active widgets) not being visible on screen, by showing them in PiP if they are not visible in any other container (#7435). Fixes #15169 and #20275.
  • Fix layout of message bubble preview in settings (#7497).
  • Prevent mutations of js-sdk owned objects as it breaks accountData (#7504). Fixes matrix-org/element-web-rageshakes#7822.
  • fallback properly with pluralized strings (#7495). Fixes #20455.
  • Consider continuations when resolving whether a tile is last in section (#7461). Fixes #20368 and #20369.
  • Fix read receipts and sent indicators for bubble layout (#7460). Fixes #18298 and #20345.
  • null-guard dataset mxTheme to prevent html exports from exploding (#7493). Fixes #20453.
  • Fix avatar container overlapping give feedback cta (#7491). Fixes matrix-org/element-web-rageshakes#7987.
  • Fix jump to bottom button working when on a permalink (#7494). Fixes #19813.
  • Remove the Description from the location picker (#7485).
  • Fix look of the untrusted device dialog (#7487). Fixes #20447. Contributed by @SimonBrandner.
  • Hide maximise button in the sticker picker (#7488). Fixes #20443. Contributed by @SimonBrandner.
  • Fix space ordering to match newer spec (#7481).
  • Fix typing notification colors (#7490). Fixes #20144. Contributed by @SimonBrandner.
  • fix fallback for pluralized strings (#7480). Fixes #20426.
  • Fix right panel soft crashes chat rooms (#7479). Fixes #20433.
  • update yarn.lock and i18n (#7476). Fixes #20426 and #20423.
  • Don't send typing notification when restoring composer draft (#7477). Fixes #20424.
  • Fix room joining spinner being incorrect if you change room mid-join (#7473).
  • Only return the approved widget capabilities instead of accepting all requested capabilities (#7454). Contributed by @dhenneke.
  • Fix quoting messages from the search view (#7466). Fixes #20353.
  • Attribute fallback i18n strings with lang attribute (#7323).
  • Fix spotlight cmd-k wrongly expanding left panel (#7463). Fixes #20399.
  • Fix room_id check when adding user widgets (#7448). Fixes #19382. Contributed by @bink.
  • Add new line in settings label (#7451). Fixes #20365.
  • Fix handling incoming redactions in EventIndex (#7443). Fixes #19326.
  • Fix room alias address isn't checked for validity before being shown as added (#7107). Fixes #19609. Contributed by @Palid.
  • Call view accessibility fixes (#7439). Fixes #18516.
  • Fix offscreen canvas breaking with split-brained firefox support (#7440).
  • Removed red shield in forwarding preview. (#7447). Contributed by @ankur12-1610.
  • Wrap status message (#7325). Fixes #20092. Contributed by @SimonBrandner.
  • Move hideSender logic into state so it causes re-render (#7413). Fixes #18448.
  • Fix dialpad positioning (#7446). Fixes #20175. Contributed by @SimonBrandner.
  • Hide non-functional list options on Suggested sublist (#7410). Fixes #20252.
  • Fix width overflow in mini composer overflow menu (#7411). Fixes #20263.
  • Fix being wrongly sent to Home space when creating/joining/leaving rooms (#7418). Fixes matrix-org/element-web-rageshakes#7331 #20246 and #20240.
  • Fix HTML Export where the data-mx-theme is Light not light (#7415).
  • Don't disable username/password fields whilst doing wk-lookup (#7438). Fixes #20121.
  • Prevent keyboard propagation out of context menus (#7437). Fixes #20317.
  • Fix nulls leaking into geo urls (#7433).
  • Fix zIndex of peristent apps in miniMode (#7429).
  • Space panel should watch spaces for space name changes (#7432).
  • Fix list formatting alternating on edit (#7422). Fixes #20073. Contributed by @renancleyson-dev.
  • Don't show Testing small changes without UIFeature.Feedback (#7427). Fixes #20298.
  • Fix invisible toggle space panel button (#7426). Fixes #20279.
  • Fix legacy breadcrumbs wrongly showing up (#7425).
  • Space Panel use SettingsStore instead of SpaceStore as source of truth (#7404). Fixes #20250.
  • Fix inline code block nowrap issue (#7406).
  • Fix notification badge for All Rooms space (#7401). Fixes #20229.
  • Show error if could not load space hierarchy (#7399). Fixes #20221.
  • Increase gap between ELS and the subsequent event to prevent overlap (#7391). Fixes #18319.
  • Fix list of members in space preview (#7356). Fixes #19781.
  • Fix sizing of e2e shield in bubble layout (#7394). Fixes #19090.
  • Fix bubble radius wrong when followed by a state event from same user (#7393). Fixes #18982.
  • Fix alignment between ELS and Events in bubble layout (#7392). Fixes #19652 and #19057.
  • Don't include the accuracy parameter in location events if accuracy could not be determined. (#7375).
  • Make compact layout only apply to Modern layout (#7382). Fixes #18412.
  • Pin qrcode to fix e2e verification bug (#7378). Fixes #20188.
  • Add internationalisation to progress strings in room export dialog (#7385). Fixes #20208.
  • Prevent escape to cancel edit from also scrolling to bottom (#7380). Fixes #20182.
  • Fix narrow mode composer buttons for polls labs (#7386). Fixes #20067.
  • Fix useUserStatusMessage exploding on unknown user (#7365).
  • Fix room join spinner in room list header (#7364). Fixes #20139.
  • Fix room search sometimes not opening spotlight (#7363). Fixes matrix-org/element-web-rageshakes#7288.

Changes in [1.9.9-rc.1](https://github.com/vector-im/element-web/releases/tag/v1.9.9-rc.1) (2022-01-11)

✨ Features

  • Ship maximised widgets and remove feature flag (#7509).
  • Properly maintain aspect ratio of inline images (#7503).
  • Add zoom buttons to the location view (#7482).
  • Remove bubble from around location events (#7459). Fixes #20323.
  • Disable "Publish this room" option in invite only rooms (#7441). Fixes #6596. Contributed by @aaronraimist.
  • Add permission dropdown for sending reactions (#7492). Fixes #20450.
  • Give secret key field an id (#7489). Fixes #20390. Contributed by @SimonBrandner.
  • Display a tooltip when you hover over a location (#7472).
  • Open map in a dialog when it is clicked (#7465).
  • a11y - wrap notification level radios in fieldsets (#7471).
  • Wrap inputs in fieldsets in Space visibility settings (#7350).
  • History based navigation with new right panel store (#7398). Fixes #19686 #19660 and #19634.
  • Associate room alias warning with public option in settings (#7430).
  • Disable quick reactions button when no permissions (#7412). Fixes #20270.
  • Allow opening a map view in OpenStreetMap (#7428).
  • Display the user's avatar when they shared their location (#7424).
  • Remove the Forward and Share buttons for location messages only (#7423).
  • Add configuration to disable relative date markers in timeline (#7405).
  • Space preferences for whether or not you see DMs in a Space (#7250). Fixes #19529 and #19955.
  • Have LocalEchoWrapper emit updates so the app can react faster (#7358). Fixes #19749.
  • Use semantic heading on dialog component (#7383).
  • Add /jumptodate slash command (#7372). Fixes #7677.
  • Update room context menu copy (#7361). Fixes #20133.
  • Use lazy rendering in the AddExistingToSpaceDialog (#7369). Fixes #18784.
  • Tweak FacePile tooltip to include whether or not you are included (#7367). Fixes #17278.

🐛 Bug Fixes

  • Ensure group audio-only calls don't switch on the webcam on join (#20234). Fixes #20212.
  • Fix wrongly wrapping code blocks, breaking line numbers (#7507). Fixes #20316.
  • Set header buttons to no phase when right panel is closed (#7506).
  • Fix active Jitsi calls (and other active widgets) not being visible on screen, by showing them in PiP if they are not visible in any other container (#7435). Fixes #15169 and #20275.
  • Fix layout of message bubble preview in settings (#7497).
  • Prevent mutations of js-sdk owned objects as it breaks accountData (#7504). Fixes matrix-org/element-web-rageshakes#7822.
  • fallback properly with pluralized strings (#7495). Fixes #20455.
  • Consider continuations when resolving whether a tile is last in section (#7461). Fixes #20368 and #20369.
  • Fix read receipts and sent indicators for bubble layout (#7460). Fixes #18298 and #20345.
  • null-guard dataset mxTheme to prevent html exports from exploding (#7493). Fixes #20453.
  • Fix avatar container overlapping give feedback cta (#7491). Fixes matrix-org/element-web-rageshakes#7987.
  • Fix jump to bottom button working when on a permalink (#7494). Fixes #19813.
  • Remove the Description from the location picker (#7485).
  • Fix look of the untrusted device dialog (#7487). Fixes #20447. Contributed by @SimonBrandner.
  • Hide maximise button in the sticker picker (#7488). Fixes #20443. Contributed by @SimonBrandner.
  • Fix space ordering to match newer spec (#7481).
  • Fix typing notification colors (#7490). Fixes #20144. Contributed by @SimonBrandner.
  • fix fallback for pluralized strings (#7480). Fixes #20426.
  • Fix right panel soft crashes chat rooms (#7479). Fixes #20433.
  • update yarn.lock and i18n (#7476). Fixes #20426 and #20423.
  • Don't send typing notification when restoring composer draft (#7477). Fixes #20424.
  • Fix room joining spinner being incorrect if you change room mid-join (#7473).
  • Only return the approved widget capabilities instead of accepting all requested capabilities (#7454). Contributed by @dhenneke.
  • Fix quoting messages from the search view (#7466). Fixes #20353.
  • Attribute fallback i18n strings with lang attribute (#7323).
  • Fix spotlight cmd-k wrongly expanding left panel (#7463). Fixes #20399.
  • Fix room_id check when adding user widgets (#7448). Fixes #19382. Contributed by @bink.
  • Add new line in settings label (#7451). Fixes #20365.
  • Fix handling incoming redactions in EventIndex (#7443). Fixes #19326.
  • Fix room alias address isn't checked for validity before being shown as added (#7107). Fixes #19609. Contributed by @Palid.
  • Call view accessibility fixes (#7439). Fixes #18516.
  • Fix offscreen canvas breaking with split-brained firefox support (#7440).
  • Removed red shield in forwarding preview. (#7447). Contributed by @ankur12-1610.
  • Wrap status message (#7325). Fixes #20092. Contributed by @SimonBrandner.
  • Move hideSender logic into state so it causes re-render (#7413). Fixes #18448.
  • Fix dialpad positioning (#7446). Fixes #20175. Contributed by @SimonBrandner.
  • Hide non-functional list options on Suggested sublist (#7410). Fixes #20252.
  • Fix width overflow in mini composer overflow menu (#7411). Fixes #20263.
  • Fix being wrongly sent to Home space when creating/joining/leaving rooms (#7418). Fixes matrix-org/element-web-rageshakes#7331 #20246 and #20240.
  • Fix HTML Export where the data-mx-theme is Light not light (#7415).
  • Don't disable username/password fields whilst doing wk-lookup (#7438). Fixes #20121.
  • Prevent keyboard propagation out of context menus (#7437). Fixes #20317.
  • Fix nulls leaking into geo urls (#7433).
  • Fix zIndex of peristent apps in miniMode (#7429).
  • Space panel should watch spaces for space name changes (#7432).
  • Fix list formatting alternating on edit (#7422). Fixes #20073. Contributed by @renancleyson-dev.
  • Don't show Testing small changes without UIFeature.Feedback (#7427). Fixes #20298.
  • Fix invisible toggle space panel button (#7426). Fixes #20279.
  • Fix legacy breadcrumbs wrongly showing up (#7425).
  • Space Panel use SettingsStore instead of SpaceStore as source of truth (#7404). Fixes #20250.
  • Fix inline code block nowrap issue (#7406).
  • Fix notification badge for All Rooms space (#7401). Fixes #20229.
  • Show error if could not load space hierarchy (#7399). Fixes #20221.
  • Increase gap between ELS and the subsequent event to prevent overlap (#7391). Fixes #18319.
  • Fix list of members in space preview (#7356). Fixes #19781.
  • Fix sizing of e2e shield in bubble layout (#7394). Fixes #19090.
  • Fix bubble radius wrong when followed by a state event from same user (#7393). Fixes #18982.
  • Fix alignment between ELS and Events in bubble layout (#7392). Fixes #19652 and #19057.
  • Don't include the accuracy parameter in location events if accuracy could not be determined. (#7375).
  • Make compact layout only apply to Modern layout (#7382). Fixes #18412.
  • Pin qrcode to fix e2e verification bug (#7378). Fixes #20188.
  • Add internationalisation to progress strings in room export dialog (#7385). Fixes #20208.
  • Prevent escape to cancel edit from also scrolling to bottom (#7380). Fixes #20182.
  • Fix narrow mode composer buttons for polls labs (#7386). Fixes #20067.
  • Fix useUserStatusMessage exploding on unknown user (#7365).
  • Fix room join spinner in room list header (#7364). Fixes #20139.
  • Fix room search sometimes not opening spotlight (#7363). Fixes matrix-org/element-web-rageshakes#7288.

Changelogs for older versions can be found here.


Changelogs CHANGELOG 2023 (`docs/changelogs/CHANGELOG-2023.md`)

Changes in [1.11.52](https://github.com/element-hq/element-web/releases/tag/v1.11.52) (2023-12-19)

✨ Features

  • Keep more recent rageshake logs (#12003). Contributed by @richvdh.

🐛 Bug Fixes

  • Fix bug which prevented correct clean up of rageshake store (#12002). Contributed by @richvdh.
  • Set up key backup using non-deprecated APIs (#12005). Contributed by @andybalaam.
  • Fix notifications appearing for old events (#3946). Contributed by @dbkr.
  • Prevent phantom notifications from events not in a room's timeline (#3942). Contributed by @dbkr.

Changes in [1.11.51](https://github.com/vector-im/element-web/releases/tag/v1.11.51) (2023-12-05)

✨ Features

  • Improve debian package and docs (#26618). Contributed by @t3chguy.

🦖 Deprecations

  • Remove Quote from MessageContextMenu as it is unsupported by WYSIWYG (#11914). Contributed by @t3chguy.

✨ Features

  • Always allow call.member events on new rooms (#11948). Contributed by @toger5.
  • Right panel: view third party invite info without clearing history (#11934). Contributed by @kerryarchibald.
  • Allow switching to system emoji font (#11925). Contributed by @t3chguy.
  • Update open in other tab message (#11916). Contributed by @weeman1337.
  • Add menu for legacy and element call in 1:1 rooms (#11910). Contributed by @toger5.
  • Add ringing for matrixRTC (#11870). Contributed by @toger5.

🐛 Bug Fixes

  • Keep device language when it has been previosuly set, after a successful delegated authentication flow that clears localStorage (#11902). Contributed by @mgcm.
  • Fix misunderstanding of functional members (#11918). Contributed by @toger5.
  • Fix: Video Room Chat Header Button Removed (#11911). Contributed by @kerryarchibald.
  • Fix "not attempting encryption" warning (#11899). Contributed by @richvdh.

Changes in [1.11.50](https://github.com/vector-im/element-web/releases/tag/v1.11.50) (2023-11-21)

✨ Features

  • Ship element-web as a debian package (#26533). Contributed by @t3chguy.
  • Update room summary card header (#11823). Contributed by @germain-gg.
  • Add feature flag for disabling encryption in Element Call (#11837). Contributed by @toger5.
  • Adapt the rendering of extra icons in the room header (#11835). Contributed by @charlynguyen.
  • Implement new unreachable state and fix broken string ref (#11748). Contributed by @MidhunSureshR.
  • Allow adding extra icons to the room header (#11799). Contributed by @charlynguyen.

🐛 Bug Fixes

  • Room header: do not collapse avatar or facepile (#11866). Contributed by @kerryarchibald.
  • New right panel: fix button alignment in memberlist (#11861). Contributed by @kerryarchibald.
  • Use the correct video call icon variant (#11859). Contributed by @robintown.
  • fix broken warning icon (#11862). Contributed by @ara4n.
  • Fix rightpanel hiding scrollbar (#11831). Contributed by @kerryarchibald.
  • Switch to updating presence via /sync calls instead of PUT /presence (#11824). Contributed by @t3chguy.

Changes in [1.11.49](https://github.com/vector-im/element-web/releases/tag/v1.11.49) (2023-11-13)

✨ Features

  • Ship element-web as a debian package (#26533). Fixes #2777.

🐛 Bug Fixes

  • Ensure setUserCreator is called when a store is assigned (#3867). Fixes vector-im/element-web#26520. Contributed by @MidhunSureshR.

Changes in [1.11.48](https://github.com/vector-im/element-web/releases/tag/v1.11.48) (2023-11-07)

✨ Features

  • Correctly fill window.matrixChat even when a Wrapper module is active (#26395). Contributed by @dhenneke.
  • Knock on a ask-to-join room if a module wants to join the room when navigating to a room (#11787). Contributed by @dhenneke.
  • Element-R: Include crypto info in sentry (#11798). Contributed by @florianduros.
  • Element-R: Include crypto info in rageshake (#11797). Contributed by @florianduros.
  • Element-R: Add current version of the rust-sdk and vodozemac (#11785). Contributed by @florianduros.
  • Fix unfederated invite dialog (#9618). Fixes vector-im/element-meta#1466 and #22102. Contributed by @owi92.
  • New right panel visual language (#11664).
  • OIDC: add friendly errors (#11184). Fixes #25665. Contributed by @kerryarchibald.

🐛 Bug Fixes

  • Fix rightpanel hiding scrollbar (#11831). Contributed by @kerryarchibald.
  • Fix multi-tab session lock on Firefox not being cleared (#11800). Fixes #26165. Contributed by @ManuelHu.
  • Deserialise spoilers back into slash command form (#11805). Fixes #26344.
  • Fix Incorrect message scaling for verification request (#11793). Fixes #24304. Contributed by @capGoblin.
  • Fix: Unable to restore a soft-logged-out session established via SSO (#11794). Fixes #25957. Contributed by @kerryarchibald.
  • Use configurable github issue links more consistently (#11796).
  • Fix io.element.late_event received_ts vs received_at (#11789).
  • Make invitation dialog scrollable when infos are too long (#11753). Contributed by @nurjinjafar.
  • Fix spoiler text-align (#11790). Contributed by @ajbura.
  • Fix: Right panel keeps showing chat when unmaximizing widget. (#11697). Fixes #26265. Contributed by @manancodes.
  • Fix margin of invite to room button (#11780). Fixes #26410.
  • Update base64 import (#11784).
  • Set max size for Element logo in search warning (#11779). Fixes #26408.
  • Fix: emoji size in room header topic, remove obsolete emoji style (#11757). Fixes #26326. Contributed by @kerryarchibald.
  • Fix: Bubble layout design is broken (#11763). Fixes #25818. Contributed by @manancodes.

Changes in [1.11.47](https://github.com/vector-im/element-web/releases/tag/v1.11.47) (2023-10-24)

🦖 Deprecations

  • Deprecate customisations in favour of Module API (#25736). Fixes #25733.

✨ Features

  • vector-im/element-x-ios/issues/1824 - Convert the apple-app-site-association file to a newer format… (#26307). Contributed by @stefanceriu.
  • Iterate io.element.late_event decoration (#11760). Fixes #26384.
  • Render timeline separator for late event groups (#11739).
  • OIDC: revoke tokens on logout (#11718). Fixes #25394. Contributed by @kerryarchibald.
  • Show io.element.late_event in MessageTimestamp when known (#11733).
  • Show all labs flags if developerMode enabled (#11746). Fixes #24571 and #8498.
  • Use Compound tooltips on MessageTimestamp to improve UX of date time discovery (#11732). Fixes #25913.
  • Consolidate 4s passphrase input fields and use stable IDs (#11743). Fixes #26228.
  • Disable upgraderoom command without developer mode enabled (#11744). Fixes #17620.
  • Avoid rendering app download buttons if disabled in config (#11741). Fixes #26309.
  • OIDC: refresh tokens (#11699). Fixes #25839. Contributed by @kerryarchibald.
  • OIDC: register (#11727). Fixes #25393. Contributed by @kerryarchibald.
  • Use stable get_login_token and remove unstable MSC3882 support (#11001). Contributed by @hughns.

🐛 Bug Fixes

  • Set max size for Element logo in search warning (#11779). Fixes #26408.
  • Avoid error when DMing oneself (#11754). Fixes #7242.
  • Fix: Message shield alignment is not right. (#11703). Fixes #26142. Contributed by @manancodes.
  • fix logging full event (#11755). Fixes #26376.
  • OIDC: use delegated auth account URL from OidcClientStore (#11723). Fixes #26305. Contributed by @kerryarchibald.
  • Fix: Members list shield alignment is not right. (#11700). Fixes #26261. Contributed by @manancodes.
  • Fix: HTML elements clickable area too wide. (#11666). Fixes #25454. Contributed by @manancodes.
  • Fix untranslated headings in the devtools dialog (#11734).
  • Fixes invite dialog alignment and pill color contrast (#11722). Contributed by @gabrc52.
  • Prevent select element in General settings overflowing in a room with very long room-id (#11597). Contributed by @ABHIXIT2.
  • Fix: Clicking on members pile does nothing. (#11657). Fixes #26164. Contributed by @manancodes.
  • Fix: Wierd shadow below room avatar in dark mode. (#11678). Fixes #26153. Contributed by @manancodes.
  • Fix start_sso / start_cas URLs failing to redirect to a authentication prompt (#11681). Contributed by @Half-Shot.

Changes in [1.11.46](https://github.com/vector-im/element-web/releases/tag/v1.11.46) (2023-10-10)

✨ Features

  • Use .well-known to discover a default rendezvous server for use with Sign in with QR (#11655). Contributed by @hughns.
  • Message layout will update according to the selected style (#10170). Fixes #21782. Contributed by @manancodes.
  • Implement MSC4039: Add an MSC for a new Widget API action to upload files into the media repository (#11311). Contributed by @dhenneke.
  • Render space pills with square corners to match new avatar (#11632). Fixes #26056.
  • Linkify room topic (#11631). Fixes #26185.
  • Show knock rooms in the list (#11573). Contributed by @maheichyk.

🐛 Bug Fixes

  • Bump matrix-web-i18n dependency to 3.1.3 (#26287)
  • Fix: Avatar shrinks with long names (#11698). Fixes #26252. Contributed by @manancodes.
  • Update custom translations to support nested fields in structured JSON (#11685).
  • Fix: Edited message remove button is hard to reach. (#11674). Fixes #24917. Contributed by @manancodes.
  • Fix: Theme selector radio button not aligned in center with the text (#11676). Fixes #25460. Contributed by @manancodes.
  • Fix: Unread notification dot aligned (#11658). Fixes #25285. Contributed by @manancodes.
  • Fix: sync intentional mentions push rules with legacy rules (#11667). Fixes #26227. Contributed by @kerryarchibald.
  • Revert "Fix regression around FacePile with overflow (#11527)" (#11634). Fixes #26209.
  • Fix: Alignment Fixed (#11648). Fixes #26169. Contributed by @manancodes.
  • Fix: onFinished added which closes the menu (#11647). Fixes #25556. Contributed by @manancodes.
  • Don't start key backups when opening settings (#11640).
  • Fix add to space avatar text centering (#11643). Fixes #26154.
  • fix avatar styling in lightbox (#11641). Fixes #26196.

Changes in [1.11.45](https://github.com/vector-im/element-web/releases/tag/v1.11.45) (2023-09-29)

🐛 Bug Fixes

  • Fix Emoji font on Safari 17 (#11673).

Changes in [1.11.44](https://github.com/vector-im/element-web/releases/tag/v1.11.44) (2023-09-26)

✨ Features

  • Make video & voice call buttons pin conference widget if unpinned (#11576). Fixes vector-im/customer-retainer#72.
  • OIDC: persist refresh token (#11249). Contributed by @kerryarchibald.
  • ElementR: Cross user verification (#11364). Fixes #25752. Contributed by @florianduros.
  • Default intentional mentions (#11602).
  • Notify users about denied access on ask-to-join rooms (#11480). Contributed by @nurjinjafar.
  • Allow setting knock room directory visibility (#11529). Contributed by @charlynguyen.

🐛 Bug Fixes

  • Revert "Fix regression around FacePile with overflow (#11527)" (#11634). Fixes #26209.
  • Escape placeholder before injecting it into the style (#11607).
  • Move ViewUser action callback to RoomView (#11495). Fixes #26040.
  • Fix room timeline search toggling behaviour edge case (#11605). Fixes #26105.
  • Avoid rendering view-message link in RoomKnocksBar unnecessarily (#11598). Contributed by @charlynguyen.
  • Use knock rooms sync to reflect the knock state (#11596). Fixes #26043 and #26044. Contributed by @charlynguyen.
  • Fix avatar in right panel not using the correct font (#11593). Fixes #26061. Contributed by @MidhunSureshR.
  • Add waits in Spotlight Cypress tests, hoping this unflakes them (#11590). Fixes #26053, #26140 #26139 and #26138. Contributed by @andybalaam.
  • Fix vertical alignment of default avatar font (#11582). Fixes #26081.
  • Fix avatars in public room & space search being flex shrunk (#11580). Fixes #26133.
  • Fix EventTile avatars being rendered with a size of 0 instead of hidden (#11558). Fixes #26075.

Changes in [1.11.43](https://github.com/vector-im/element-web/releases/tag/v1.11.43) (2023-09-15)

(No changes - bumping the version number for an element-desktop release.)

Changes in [1.11.42](https://github.com/vector-im/element-web/releases/tag/v1.11.42) (2023-09-13)

🐛 Bug Fixes

  • Update Compound to fix Firefox-specific avatar regression (#11604). Fixes #26155.

Changes in [1.11.41](https://github.com/vector-im/element-web/releases/tag/v1.11.41) (2023-09-12)

🦖 Deprecations

  • Deprecate customisations in favour of Module API (#25736). Fixes #25733.

✨ Features

  • Make SVGR icons use forward ref (#26082).
  • Add support for rendering a custom wrapper around Element (#25537). Contributed by @maheichyk.
  • Allow creating public knock rooms (#11481). Contributed by @charlynguyen.
  • Render custom images in reactions according to MSC4027 (#11087). Contributed by @sumnerevans.
  • Introduce room knocks bar (#11475). Contributed by @charlynguyen.
  • Room header UI updates (#11507). Fixes #25892.
  • Remove green "verified" bar for encrypted events (#11496).
  • Update member count on room summary update (#11488).
  • Support for E2EE in Element Call (#11492).
  • Allow requesting to join knock rooms via spotlight (#11482). Contributed by @charlynguyen.
  • Lock out the first tab if Element is opened in a second tab. (#11425). Fixes #25157.
  • Change avatar to use Compound implementation (#11448).

🐛 Bug Fixes

  • Fix vertical alignment of default avatar font (#11582). Fixes #26081.
  • Fix avatars in public room & space search being flex shrunk (#11580). Fixes #26133.
  • Fix EventTile avatars being rendered with a size of 0 instead of hidden (#11558). Fixes #26075.
  • Fix compound external assets path in bundle (#26069).
  • Use RoomStateEvent.Update for knocks (#11516). Contributed by @charlynguyen.
  • Prevent event propagation when clicking icon buttons (#11515).
  • Only display RoomKnocksBar when feature flag is enabled (#11513). Contributed by @andybalaam.
  • Fix avatars of knock members for people tab of room settings (#11506). Fixes #26083. Contributed by @charlynguyen.
  • Fixes read receipt avatar offset (#11483). Fixes #26067, #26064 #26059 and #26061.
  • Fix avatar defects (#11473). Fixes #26051 and #26046.
  • Fix consistent avatar output for Percy (#11472). Fixes #26049 and #26052.
  • Fix colour of avatar and colour matching with username (#11470). Fixes #26042.
  • Fix incompatibility of Soft Logout with Element-R (#11468).
  • Fix instances of double translation and guard translation calls using typescript (#11443).

Changes in [1.11.40](https://github.com/vector-im/element-web/releases/tag/v1.11.40) (2023-08-29)

✨ Features

  • Hide account deactivation for externally managed accounts (#11445). Fixes #26022. Contributed by @kerryarchibald.
  • OIDC: Redirect to delegated auth provider when signing out (#11432). Fixes #26000. Contributed by @kerryarchibald.
  • Disable 3pid fields in settings when m.3pid_changes capability is disabled (#11430). Fixes #25995. Contributed by @kerryarchibald.
  • OIDC: disable multi session signout for OIDC-aware servers in session manager (#11431). Contributed by @kerryarchibald.
  • Implement updated open dialog method of the Module API (#11395). Contributed by @dhenneke.
  • Polish & delabs Exploring public spaces feature (#11423).
  • Treat lists with a single empty item as plain text, not Markdown. (#6833). Fixes vector-im/element-meta#1265.
  • Allow managing room knocks (#11404). Contributed by @charlynguyen.
  • Pin the action buttons to the bottom of the scrollable dialogs (#11407). Contributed by @dhenneke.
  • Support Matrix 1.1 (drop legacy r0 versions) (#9819).

🐛 Bug Fixes

  • Fix path separator for Windows based systems (#25997).
  • Fix instances of double translation and guard translation calls using typescript (#11443).
  • Fix export type "Current timeline" to match its behaviour to its name (#11426). Fixes #25988.
  • Fix Room Settings > Notifications file upload input being shown superfluously (#11415). Fixes #18392.
  • Simplify registration with email validation (#11398). Fixes #25832 #23601 and #22297.
  • correct home server URL (#11391). Fixes #25931. Contributed by @NSV1991.
  • Include non-matching DMs in Spotlight recent conversations when the DM's userId is part of the search API results (#11374). Contributed by @mgcm.
  • Fix useRoomMembers missing updates causing incorrect membership counts (#11392). Fixes #17096.
  • Show error when searching public rooms fails (#11378).

Changes in [1.11.39](https://github.com/vector-im/element-web/releases/tag/v1.11.39) (2023-08-15)

🦖 Deprecations

  • Deprecate camelCase config options (#25800).
  • Deprecate customisations in favour of Module API (#25736). Fixes #25733.

✨ Features

  • Update labs.md for knock rooms (#25923). Contributed by @charlynguyen.
  • Package release builds of element-web in package.element.io debs (#25198).
  • Allow knocking rooms (#11353). Contributed by @charlynguyen.
  • Support adding space-restricted joins on rooms not members of those spaces (#9017). Fixes #19213.
  • Clear requiresClient and show pop-out if widget-api fails to ready (#11321). Fixes vector-im/customer-retainer#73.
  • Bump pagination sizes due to hidden events (#11342).
  • Remove display of key backup signatures from backup settings (#11333).
  • Use PassphraseFields in ExportE2eKeysDialog to enforce minimum passphrase complexity (#11222). Fixes #9478.

🐛 Bug Fixes

  • Fix "Export chat" not respecting configured time format in plain text mode (#10696). Fixes #23838. Contributed by @rashmitpankhania.
  • Fix some missing 1-count pluralisations around event list summaries (#11371). Fixes #25925.
  • Fix create subspace dialog not working for public space creation (#11367). Fixes #25916.
  • Search for users on paste (#11304). Fixes #17523. Contributed by @peterscheu-aceart.
  • Fix AppTile context menu not always showing up when it has options (#11358). Fixes #25914.
  • Fix clicking on home all rooms space notification not working (#11337). Fixes #22844.
  • Fix joining a suggested room switching space away (#11347). Fixes #25838.
  • Fix home/all rooms context menu in space panel (#11350). Fixes #25896.
  • Make keyboard handling in and out of autocomplete completions consistent (#11344). Fixes #25878.
  • De-duplicate reactions by sender to account for faulty/malicious servers (#11340). Fixes #25872.
  • Fix disable_3pid_login being ignored for the email field (#11335). Fixes #25863.
  • Upgrade wysiwyg editor for ctrl+backspace windows fix (#11324). Fixes vector-im/verticals-internal#102.
  • Unhide the view source event toggle - it works well enough (#11336). Fixes #25861.

Changes in [1.11.38](https://github.com/vector-im/element-web/releases/tag/v1.11.38) (2023-08-04)

✨ Features

  • Package release builds of element-web in package.element.io debs (#25198).

🐛 Bug Fixes

  • Revert to using the /presence API for presence (#11366)

Changes in [1.11.37](https://github.com/vector-im/element-web/releases/tag/v1.11.37) (2023-08-01)

🦖 Deprecations

  • Deprecate camelCase config options (#25800).
  • Deprecate customisations in favour of Module API (#25736). Fixes #25733.

✨ Features

  • Do not show "Forget room" button in Room View header for guest users (#10898). Contributed by @spantaleev.
  • Switch to updating presence via /sync calls instead of PUT /presence (#11223). Fixes #20809 #13877 and #4813.
  • Fix blockquote colour contrast (#11299). Fixes matrix-org/element-web-rageshakes#21800.
  • Don't hide room header buttons in video rooms and rooms with a call (#9712). Fixes #23900.
  • OIDC: Persist details in session storage, create store (#11302). Fixes #25710. Contributed by @kerryarchibald.
  • Allow setting room join rule to knock (#11248). Contributed by @charlynguyen.
  • Retry joins on 524 (Cloudflare timeout) also (#11296). Fixes #8776.
  • Make sure users returned by the homeserver search API are displayed. Don't silently drop any. (#9556). Fixes #24422. Contributed by @maxmalek.
  • Offer to unban user during invite if inviter has sufficient permissions (#11256). Fixes #3222.
  • Split join and goto slash commands, the latter shouldn't auto_join (#11259). Fixes #10128.
  • Integration work for rich text editor 2.3.1 (#11172). Contributed by @alunturner.
  • Compound color pass (#11079). Fixes vector-im/internal-planning#450 and #25547.
  • Warn when demoting self via /op and /deop slash commands (#11214). Fixes #13726.

🐛 Bug Fixes

  • Correct Jitsi preferred_domain property (#25813). Contributed by @benbz.
  • Fix edge case with sent indicator being drawn when it shouldn't be (#11320).
  • Use correct translation function for WYSIWYG buttons (#11315). Fixes vector-im/verticals-internal#109.
  • Handle empty own profile (#11319). Fixes #25510.
  • Fix peeked rooms showing up in historical (#11316). Fixes #22473.
  • Ensure consistency when rendering the sent event indicator (#11314). Fixes #17937.
  • Prevent re-filtering user directory results in spotlight (#11290). Fixes #24422.
  • Fix GIF label on dark theme (#11312). Fixes #25836.
  • Fix issues around room notification settings flaking out (#11306). Fixes #16472 #21309 and #6828.
  • Fix invite dialog showing the same user multiple times (#11308). Fixes #25578.
  • Don't show composer send button if user cannot send (#11298). Fixes #25825.
  • Restore color for sender in imageview (#11289). Fixes #25822.
  • Fix changelog dialog heading size (#11286). Fixes #25789.
  • Restore offline presence badge color (#11287). Fixes #25792.
  • Fix bubble message layout avatar overlap (#11284). Fixes #25818.
  • Fix voice call tile size (#11285). Fixes #25684.
  • Fix layout of sessions tab buttons (#11279). Fixes #25545.
  • Don't bother showing redundant tooltip on space menu (#11276). Fixes #20380.
  • Remove reply fallback from notifications (#11278). Fixes #17859.
  • Populate info.duration for audio & video file uploads (#11225). Fixes #17720.
  • Hide widget menu button if it there are no options available (#11257). Fixes #24826.
  • Fix colour regressions (#11273). Fixes #25788, #25808 #25811 and #25812.
  • Fix room view not properly maintaining scroll position (#11274). Fixes #25810.
  • Prevent user from accidentally double clicking user info admin actions (#11254). Fixes #10944.
  • Fix missing metaspace notification badges (#11269). Fixes #25679.
  • Fix clicking MXID in timeline going to matrix.to (#11263). Fixes #23342.
  • Restoring optional ligatures by resetting letter-spacing (#11202). Fixes #25727.
  • Allow emoji presentation selector to not break BigEmoji styling (#11253). Fixes #17848.
  • Make event highliht use primary content token (#11255).
  • Fix event info events size and color (#11252). Fixes #25778.
  • Fix color mapping for blockquote border (#11251). Fixes #25782.
  • Strip emoji variation when searching emoji by emoji (#11221). Fixes #18703.

Changes in [1.11.36](https://github.com/vector-im/element-web/releases/tag/v1.11.36) (2023-07-18)

🔒 Security

🦖 Deprecations

  • Deprecate customisations in favour of Module API (#25736). Fixes #25733.

✨ Features

  • OIDC: store initial screen in session storage (#25688). Fixes #25656. Contributed by @kerryarchibald.
  • Allow default_server_config as a fallback config (#25682). Contributed by @ShadowRZ.
  • OIDC: remove auth params from url after login attempt (#25664). Contributed by @kerryarchibald.
  • feat(faq): remove keyboard shortcuts button (#9342). Fixes #22625. Contributed by @gefgu.
  • GYU: Update banner (#11211). Fixes #25530. Contributed by @justjanne.
  • Linkify mxc:// URLs as links to your media repo (#11213). Fixes #6942.
  • OIDC: Log in (#11199). Fixes #25657. Contributed by @kerryarchibald.
  • Handle all permitted url schemes in linkify (#11215). Fixes #4457 and #8720.
  • Autoapprove Element Call oidc requests (#11209). Contributed by @toger5.
  • Allow creating knock rooms (#11182). Contributed by @charlynguyen.
  • Expose and pre-populate thread ID in devtools dialog (#10953).
  • Hide URL preview if it will be empty (#9029).
  • Change wording from avatar to profile picture (#7015). Fixes vector-im/element-meta#1331. Contributed by @aaronraimist.
  • Quick and dirty devtool to explore state history (#11197).
  • Consider more user inputs when calculating zxcvbn score (#11180).
  • GYU: Account Notification Settings (#11008). Fixes #24567. Contributed by @justjanne.
  • Compound Typography pass (#11103). Fixes #25548.
  • OIDC: navigate to authorization endpoint (#11096). Fixes #25574. Contributed by @kerryarchibald.

🐛 Bug Fixes

  • Fix read receipt sending behaviour around thread roots (#3600).
  • Fix missing metaspace notification badges (#11269). Fixes #25679.
  • Make checkboxes less rounded (#11224). Contributed by @andybalaam.
  • GYU: Fix issues with audible keywords without activated mentions (#11218). Contributed by @justjanne.
  • PosthogAnalytics unwatch settings on logout (#11207). Fixes #25703.
  • Avoid trying to set room account data for pinned events as guest (#11216). Fixes #6300.
  • GYU: Disable sound for DMs checkbox when DM notifications are disabled (#11210). Contributed by @justjanne.
  • force to allow calls without video and audio in embedded mode (#11131). Contributed by @EnricoSchw.
  • Fix room tile text clipping (#11196). Fixes #25718.
  • Handle newlines in user pills (#11166). Fixes #10994.
  • Limit width of user menu in space panel (#11192). Fixes #22627.
  • Add isLocation to ComposerEvent analytics events (#11187). Contributed by @andybalaam.
  • Fix: hide unsupported login elements (#11185). Fixes #25711. Contributed by @kerryarchibald.
  • Scope smaller font size to user info panel (#11178). Fixes #25683.
  • Apply i18n to strings in the html export (#11176).
  • Inhibit url previews on MXIDs containing slashes same as those without (#11160).
  • Make event info size consistent with state events (#11181).
  • Fix markdown content spacing (#11177). Fixes #25685.
  • Fix font-family definition for emojis (#11170). Fixes #25686.
  • Fix spurious error sending receipt in thread errors (#11157).
  • Consider the empty push rule actions array equiv to deprecated dont_notify (#11155). Fixes #25674.
  • Only trap escape key for cancel reply if there is a reply (#11140). Fixes #25640.
  • Update linkify to 4.1.1 (#11132). Fixes #23806.

Changes in [1.11.35](https://github.com/vector-im/element-web/releases/tag/v1.11.35) (2023-07-04)

🦖 Deprecations

  • Remove feature_favourite_messages as it is has been abandoned for now (#11097). Fixes #25555.

✨ Features

  • Don't setup keys on login when encryption is force disabled (#11125). Contributed by @kerryarchibald.
  • OIDC: attempt dynamic client registration (#11074). Fixes #25468 and #25467. Contributed by @kerryarchibald.
  • OIDC: Check static client registration and add login flow (#11088). Fixes #25467. Contributed by @kerryarchibald.
  • Improve message body output from plain text editor (#11124). Contributed by @alunturner.
  • Disable encryption toggle in room settings when force disabled (#11122). Contributed by @kerryarchibald.
  • Add .well-known config option to force disable encryption on room creation (#11120). Contributed by @kerryarchibald.
  • Handle permalinks in room topic (#11115). Fixes #23395.
  • Add at room avatar for RTE (#11106). Contributed by @alunturner.
  • Remove new room breadcrumbs (#11104).
  • Update rich text editor dependency and associated changes (#11098). Contributed by @alunturner.
  • Implement new model, hooks and reconcilation code for new GYU notification settings (#11089). Contributed by @justjanne.
  • Allow maintaining a different right panel width for thread panels (#11064). Fixes #25487.
  • Make AppPermission pane scrollable (#10954). Fixes #25438 and #25511. Contributed by @luixxiul.
  • Integrate compound design tokens (#11091). Fixes vector-im/internal-planning#450.
  • Don't warn about the effects of redacting state events when redacting non-state-events (#11071). Fixes #8478.
  • Allow specifying help URLs in config.json (#11070). Fixes #15268.

🐛 Bug Fixes

  • Fix error when generating error for polling for updates (#25609).
  • Fix spurious notifications on non-live events (#11133). Fixes #24336.
  • Prevent auto-translation within composer (#11114). Fixes #25624.
  • Fix caret jump when backspacing into empty line at beginning of editor (#11128). Fixes #22335.
  • Fix server picker not allowing you to switch from custom to default (#11127). Fixes #25650.
  • Consider the unthreaded read receipt for Unread dot state (#11117). Fixes #24229.
  • Increase RTE resilience (#11111). Fixes #25277. Contributed by @alunturner.
  • Fix RoomView ignoring alias lookup errors due to them not knowing the roomId (#11099). Fixes #24783 and #25562.
  • Fix style inconsistencies on SecureBackupPanel (#11102). Fixes #25615. Contributed by @luixxiul.
  • Remove unknown MXIDs from invite suggestions (#11055). Fixes #25446.
  • Reduce volume of ring sounds to normalised levels (#9143). Contributed by @JMoVS.
  • Fix slash commands not being enabled in certain cases (#11090). Fixes #25572.
  • Prevent escape in threads from sending focus to main timeline composer (#11061). Fixes #23397.

Changes in [1.11.34](https://github.com/vector-im/element-web/releases/tag/v1.11.34) (2023-06-20)

✨ Features

  • OIDC: add delegatedauthentication to validated server config (#11053). Contributed by @kerryarchibald.
  • Allow image pasting in plain mode in RTE (#11056). Contributed by @alunturner.
  • Show room options menu if "UIComponent.roomOptionsMenu" is enabled (#10365). Contributed by @maheichyk.
  • Allow image pasting in rich text mode in RTE (#11049). Contributed by @alunturner.
  • Update voice broadcast redaction to use MSC3912 with_rel_type instead of with_relations (#11014). Fixes #25471.
  • Add config to skip widget_build_url for DM rooms (#11044). Fixes vector-im/customer-retainer#74.
  • Inhibit interactions on forward dialog message previews (#11025). Fixes #23459.
  • Removed DecryptionFailureBar.tsx (#11027). Fixes vector-im/element-meta#1358. Contributed by @florianduros.

🐛 Bug Fixes

  • Fix translucent TextualEvent on search results panel (#10810). Fixes #25292. Contributed by @luixxiul.
  • Matrix matrix scheme permalink constructor not stripping query params (#11060). Fixes #25535.
  • Fix: "manually verify by text" does nothing (#11059). Fixes #25375. Contributed by @kerryarchibald.
  • Make group calls respect the ICE fallback setting (#11047). Fixes vector-im/voip-internal#65.
  • Align list items on the tooltip to the start (#11041). Fixes #25355. Contributed by @luixxiul.
  • Clear thread panel event permalink when changing rooms (#11024). Fixes #25484.
  • Fix spinner placement on pinned widgets being reloaded (#10970). Fixes #25431. Contributed by @luixxiul.

Changes in [1.11.33](https://github.com/vector-im/element-web/releases/tag/v1.11.33) (2023-06-09)

🐛 Bug Fixes

  • Bump matrix-react-sdk to v3.73.1 for matrix-js-sdk v26.0.1. Fixes #25526.

Changes in [1.11.32](https://github.com/vector-im/element-web/releases/tag/v1.11.32) (2023-06-06)

✨ Features

  • Redirect to the SSO page if sso_redirect_options.on_welcome_page is enabled and the URL hash is empty (#25495). Contributed by @dhenneke.
  • vector/index.html: Allow fetching blob urls (#25336). Contributed by @SuperKenVery.
  • When joining room in sub-space join the parents too (#11011).
  • Include thread replies in message previews (#10631). Fixes #23920.
  • Use semantic headings in space preferences (#11021). Contributed by @kerryarchibald.
  • Use semantic headings in user settings - Ignored users (#11006). Contributed by @kerryarchibald.
  • Use semantic headings in user settings - profile (#10973). Fixes #25461. Contributed by @kerryarchibald.
  • Use semantic headings in user settings - account (#10972). Contributed by @kerryarchibald.
  • Support Insert from iPhone or iPad in Safari (#10851). Fixes #25327. Contributed by @SuperKenVery.
  • Specify supportedStages for User Interactive Auth (#10975). Fixes #19605.
  • Pass device id to widgets (#10209). Contributed by @Fox32.
  • Use semantic headings in user settings - discovery (#10838). Contributed by @kerryarchibald.
  • Use semantic headings in user settings - Notifications (#10948). Contributed by @kerryarchibald.
  • Use semantic headings in user settings - spellcheck and language (#10959). Contributed by @kerryarchibald.
  • Use semantic headings in user settings Appearance (#10827). Contributed by @kerryarchibald.
  • Use semantic heading in user settings Sidebar & Voip (#10782). Contributed by @kerryarchibald.
  • Use semantic headings in user settings Security (#10774). Contributed by @kerryarchibald.
  • Use semantic headings in user settings - integrations and account deletion (#10837). Fixes #25378. Contributed by @kerryarchibald.
  • Use semantic headings in user settings Preferences (#10794). Contributed by @kerryarchibald.
  • Use semantic headings in user settings Keyboard (#10793). Contributed by @kerryarchibald.
  • RTE plain text mentions as pills (#10852). Contributed by @alunturner.
  • Allow welcome.html logo to be replaced by config (#25339). Fixes #8636.
  • Use semantic headings in user settings Labs (#10773). Contributed by @kerryarchibald.
  • Use semantic list elements for menu lists and tab lists (#10902). Fixes #24928.
  • Fix aria-required-children axe violation (#10900). Fixes #25342.
  • Enable pagination for overlay timelines (#10757). Fixes vector-im/voip-internal#107.
  • Add tooltip to disabled invite button due to lack of permissions (#10869). Fixes #9824.
  • Respect configured auth_header_logo_url for default Welcome page (#10870).
  • Specify lazy loading for avatars (#10866). Fixes #1983.
  • Room and user mentions for plain text editor (#10665). Contributed by @alunturner.
  • Add audible notifcation on broadcast error (#10654). Fixes #25132.
  • Fall back from server generated thumbnail to original image (#10853).
  • Use semantically correct elements for room sublist context menu (#10831). Fixes vector-im/customer-retainer#46.
  • Avoid calling prepareToEncrypt onKeyDown (#10828).
  • Allows search to recognize full room links (#8275). Contributed by @bolu-tife.
  • "Show rooms with unread messages first" should not be on by default for new users (#10820). Fixes #25304. Contributed by @kerryarchibald.
  • Fix emitter handler leak in ThreadView (#10803).
  • Add better error for email invites without identity server (#10739). Fixes #16893.
  • Move reaction message previews out of labs (#10601). Fixes #25083.
  • Sort muted rooms to the bottom of their section of the room list (#10592). Fixes #25131. Contributed by @kerryarchibald.
  • Use semantic headings in user settings Help & About (#10752). Contributed by @kerryarchibald.
  • use ExternalLink components for external links (#10758). Contributed by @kerryarchibald.
  • Use semantic headings in space settings (#10751). Contributed by @kerryarchibald.
  • Use semantic headings for room settings content (#10734). Contributed by @kerryarchibald.

🐛 Bug Fixes

  • Use consistent fonts for Japanese text (#10980). Fixes #22333 and #23899.
  • Fix: server picker validates unselected option (#11020). Fixes #25488. Contributed by @kerryarchibald.
  • Fix room list notification badges going missing in compact layout (#11022). Fixes #25372.
  • Fix call to startSingleSignOn passing enum in place of idpId (#10998). Fixes #24953.
  • Remove hover effect from user name on a DM creation UI (#10887). Fixes #25305. Contributed by @luixxiul.
  • Fix layout regression