VS Code - Auto rename HTML tags in React, Vue, Svelte, Nunjucks, and others
Tags: vscode, webdev, javascript, tooling
Published: 2023-05-08 21:34:39

In a previous post, [*VS Code - You don't need that extension*](https://www.roboleary.net/vscode/2020/08/05/dont-need-extensions.html), I covered some settings that offer the same functionality as popular extensions. One topic I covered was renaming paired HTML tags in a single edit, this is also referred to as linked editing of HTML tags.

A bone of contention was the "linked editing" setting only supported HTML and XML files. There was grumbling that this behaviour was not available in JSX. There has been [a long standing issue to implement this feature for JSX](https://github.com/microsoft/vscode/issues/85707), and finally it has been resolved! **In [version 1.78 (April 2023)](https://code.visualstudio.com/updates/v1_78#_rename-matching-jsx-tags-using-f2), you can auto rename tags in JSX too**.

I wanted to take the opportunity to take a look at other frameworks and languages that contain embedded HTML such as Vue and Nunjucks, to see if it there is a consistent experience for renaming HTML tags in this manner. Some language feature extensions provide this functionality, some don't.

## TLDR

To enable auto renaming of tags in HTML, XML, and JSX (React and friends), you can enable the **`editor.linkedEditing`** setting in your *settings.json* file. **This setting is false by default, so you must explicit set it!**

```json
{
  "editor.linkedEditing": true,
	
  "javascript.preferences.renameMatchingJsxTags" : true,
  "typescript.preferences.renameMatchingJsxTags" : true
}
```

For JSX, there are 2 related settings to toggle this feature on or off for JavaScript and TypeScript. They are enabled by default, so you can exclude them from your *settings.json*.

## Auto rename HTML tags

Let's recap how things operate in HTML and XML files first, before we move onto JSX and others.

### Auto rename tags in HTML and XML files

If you want auto renaming of tags in HTML, you *must* set the **`Editor: Linked Editing`** setting to `true`. This setting is false by default.

If you want to edit your *settings.json* file directly, it is `editor.linkedEditing` setting you are after.

```json
{
  "editor.linkedEditing": true
}
```

This enables you to rename a tag by editing it directly, a mirrored cursor will automatically rename the matching tag.

<video src="https://www.roboleary.net/assets/img/blog/2023-05-08-auto-rename-tags-jsx-html/rename-tags-html.mp4" controls autoplay="true" muted loop>

You can also use the **`Rename Symbol`** command to rename the tag via an inline dialog. The keyboard shortcut for this is [[ F2 ]].

<video src="https://www.roboleary.net/assets/img/blog/2023-05-08-auto-rename-tags-jsx-html/rename-tags-html-rename-symbol.mp4" controls autoplay="true" muted loop>

### Auto rename tags in JSX (React)

Since version 1.79 (May 2023) of VS Code, **auto renaming tags in JSX is also controlled by the `editor.linkedEditing` setting.**

There is one thing to keep in mind: **your project *must* use Typescript version 5.1 or later.** VS Code version 1.79 uses TypeScript version 5.1 by default, so you are unlikely to run into an issue for new projects.

If your project workspace is setup to use TypeScript version 5 or less, auto renaming tags will fail. The command **`Rename Symbol`**, you will get an error saying "You cannot rename elements that are defined in a 'node_modules' folder" as below. This is not a helpful error!

<img src="https://www.roboleary.net/assets/img/blog/2023-05-08-auto-rename-tags-jsx-html/rename-tags-react-rename-symbol-error.png" width="1057" height="247" alt="Rename html tag pairs in JSX using the 'rename symbol' command. It gives an error when you are not using Typescript 5.1 or later in the workspace. The error says: You cannot rename elements that are defined in a 'node_modules' folder." loading="lazy">

To change what version of TypeScript your workspace is using, you can run the commmand **`TypeScript: Select TypeScript Version`**. You can read more about that in the [*Using newer TypeScript versions* section in the docs](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-newer-typescript-versions).

This feature is managed by 2 different settings that are enabled by default:
- `javascript.preferences.renameMatchingJsxTags` for JavaScript files
- `typescript.preferences.renameMatchingJsxTags` for TypeScript files

### Auto rename tags in Vue

The [Vue Language Features (Volar) extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar) supports auto renaming tags.

Similar to HTML, you can rename tags by live editing using mirrored cursors, or using the command **`Rename Symbol`**.

If you use the [Vetur extension](https://marketplace.visualstudio.com/items?itemName=octref.vetur) for Vue language features, you are out of luck. There is a [long-standing request for adding this behaviour to Vetur](https://github.com/vuejs/vetur/issues/565).

### Auto rename tags in Svelte

The [Svelte for VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) supports auto renaming tags.

I recommend using the command **`Rename Symbol`** to rename matching tags, I found using mirrored cursors for renaming tags to be a bit buggy.

### Auto rename tags in other languages such as Nunjucks

Unfortunately, the language feature extension for Nunjucks -- [Nunjucks Template](https://marketplace.visualstudio.com/items?itemName=eseom.nunjucks-template) -- does not offer this functionality!

The command **`Emmet: Update tag`** does a similar job. Emmet is not enabled for Nunjucks by default, so I added it. It looks like it works well.

<video src="https://www.roboleary.net/assets/img/blog/2023-05-08-auto-rename-tags-jsx-html/emmet-update-tag-nunjucks.mp4" controls autoplay muted loop>

You can add support for Emmet in a language by adding the following to your *settings.json*:

```json
"emmet.includeLanguages": {
    "njk": "html"
}
```

The syntax is kind of weird! The [docs does not explain why you need to associate the language you want Emmet support in with the `html` language ID](https://code.visualstudio.com/docs/editor/emmet#_emmet-abbreviations-in-other-file-types), but that is how you do it for a HTML-like language!

I liked it enough that I changed the keyboard shortcut for [[ F2 ]] to use the **`Emmet: Update tag`** command for nunjucks files. I added the following to my *keybindings.json*:

```json
{
    "key": "f2",
    "command": "editor.emmet.action.updateTag",
    "when": "editorTextFocus && editorLangId == 'njk'"
}
```

In lieu of `your favourite language` supporting auto renaming matching tags, the **`Emmet: Update tag`** command is a reasonable workaround. Your mileage may vary though!

## Final words

Auto renaming tags is one of those developer experience improvements that makes life just a little bit easier. One less thing to worry about.

I think that we are victims of the multitude of template languages and JavaScript frameworks that utlitize HTML in different ways. It impedes "nice to have" features like this from being widely available because *so many* features are being redone for each variant. It has taken a long time for this to be implemented by VS Code for React, and you would think React would be nailed-on to get this functionality first, and early.

It is good to see that the other popular frameworks such as Vue and Svelte have auto renaming tags implemented. Beyond that you may have less luck. Using the command **`Emmet: Update tag`** works quite well for many languages as a workaround.

I recommend using the **`Rename Symbol`** command as it is more consistently implemented across languages. Live editing with mirrored cursors is not available everywhere.

Thanks for reading!