---
title: Docusaurus 2.3
authors: [slorber]
tags: [release]
image: ./img/social-card.png
date: 2023-01-27
---

We are happy to announce **Docusaurus 2.3**.

The upgrade should be easy: as explained in our [release process documentation](/community/release-process), minor versions respect [Semantic Versioning](https://semver.org/).

![Docusaurus 2.2 social card](./img/social-card.png)

<!--truncate-->

## Highlights

### Google Tag Manager plugin

Google Tag Manager is a tag management system that allows great flexibility. It enables analytics and marketing teams to easily load other third-party trackers and fire analytics tags.

We now have a [`@docusaurus/plugin-google-tag-manager`](/docs/api/plugins/@docusaurus/plugin-google-tag-manager/) package that you can use alongside or as an alternative to the existing [gtag.js plugin](/docs/api/plugins/@docusaurus/plugin-google-gtag/) (refer to [this doc](https://support.google.com/tagmanager/answer/7582054) to understand when to use which solution).

:::caution Google is sunsetting Universal Analytics

[Google will sunset its Universal Analytics](https://blog.google/products/marketingplatform/analytics/prepare-for-future-with-google-analytics-4/) on **July 1, 2023**, and ask users to migrate to **Google Analytics 4**.

Therefore, we are also **deprecating our existing [`@docusaurus/plugin-google-analytics`](/docs/api/plugins/@docusaurus/plugin-google-analytics)** package. Docusaurus users should create a new Google Analytics 4 property, and migrate to the [gtag.js plugin](/docs/api/plugins/@docusaurus/plugin-google-gtag/), or the [Google Tag Manager plugin](/docs/api/plugins/@docusaurus/plugin-google-tag-manager/). Refer to the [dedicated Docusaurus issue](https://github.com/facebook/docusaurus/issues/7221) for details and questions.

:::

### Tabs Query String Support

It is now possible to link a selected tab to a query string parameter. When a tab is selected, it will be stored in your browser URL as a `?qs-param=tab-value` search parameter.

This feature allows deep-linking to a specific documentation tab that will pre-selected on page load.

When used alongside the `groupId` prop, the query string tab value takes precedence over the `localStorage` value.

Make sure to check the [documentation](/docs/markdown-features/tabs#query-string) and the demo below to understand how it works:

import BrowserWindow from '@site/src/components/BrowserWindow';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

```tsx
<Tabs groupId="current-os" queryString>
  <TabItem value="android" label="Android">
    Android
  </TabItem>
  <TabItem value="ios" label="iOS">
    iOS
  </TabItem>
</Tabs>
```

<BrowserWindow>
  <Tabs groupId="current-os" queryString>
    <TabItem value="android" label="Android">
      Android
    </TabItem>
    <TabItem value="ios" label="iOS">
      iOS
    </TabItem>
  </Tabs>
</BrowserWindow>

### Nested admonitions

It is now possible to nest one admonition within another by adding extra colons for the outer/enclosing admonition:

```md
::::tip nested admonitions

You can now nest one admonition within another!

:::danger

Use this sparingly when it makes sense.

:::

::::
```

::::tip nested admonitions

You can now nest one admonition within another!

:::danger

Use this sparingly when it makes sense.

:::

::::

### Blog `createFeedItems`

A new blog plugin option [`feedOptions.createFeedItems`](/docs/api/plugins/@docusaurus/plugin-content-blog/#CreateFeedItemsFn) gives you more control over the RSS/Atom feed generation. It is now possible to transform/filter/limit feed items through a new callback.

```tsx title="docusaurus.config.js"
[
  '@docusaurus/preset-classic',
  {
    blog: {
      feedOptions: {
        // highlight-start
        createFeedItems: async (params) => {
          const {blogPosts, defaultCreateFeedItems, ...rest} = params;
          return defaultCreateFeedItems({
            // keep only the 10 most recent blog posts in the feed
            blogPosts: blogPosts.filter((item, index) => index < 10),
            ...rest,
          });
        },
        // highlight-end
      },
    },
  },
];
```

### Translations

We added or completed the default theme translation support for multiple languages:

- 🇸🇮 [#8541](https://github.com/facebook/docusaurus/pull/8541) Slovenian
- 🇹🇷 [#8289](https://github.com/facebook/docusaurus/pull/8289) Turkish
- 🇮🇷 [#8406](https://github.com/facebook/docusaurus/pull/8406) Farsi
- 🇵🇱 [#8525](https://github.com/facebook/docusaurus/pull/8525) Polish
- 🇨🇳 [#8423](https://github.com/facebook/docusaurus/pull/8423) Chinese
- 🇸🇪 [#8312](https://github.com/facebook/docusaurus/pull/8312) Swedish
- 🇻🇳 [#8450](https://github.com/facebook/docusaurus/pull/8450) Vietnamese

:::tip

Completing theme translations is an [ongoing effort](https://github.com/facebook/docusaurus/issues/3526) and an easy way to contribute to Docusaurus. We add new theme features regularly, for which we often [need new translations](https://github.com/facebook/docusaurus/issues/3526).

:::

## Other changes

Other notable changes include:

- [#8463](https://github.com/facebook/docusaurus/pull/8463) and [#8328](https://github.com/facebook/docusaurus/pull/8328): fix some annoying Docusaurus layout issues
- [#8539](https://github.com/facebook/docusaurus/pull/8539): Algolia plugin `options.searchPagePath` should be correctly applied to search modal footer
- [#8462](https://github.com/facebook/docusaurus/pull/8462): Algolia plugin now makes it easier to transform displayed search results with custom logic
- [#8397](https://github.com/facebook/docusaurus/pull/8397): the `deploy` CLI now understands git url `insteadOf` config

Check the **[2.3.0 changelog entry](/changelog/2.3.0)** for an exhaustive list of changes.
