<!--
  canonical-url: https://www.avonture.be/blog/docusaurus-lazy-loading
  published:     2025-08-27
  This is a static plain-Markdown mirror generated at build time.
  Visit the canonical URL above for the fully rendered page, with images and interactive components.
-->

# Overrides the generation of img tags with Docusaurus

> Learn how to customize the rendering of <img> tags in Docusaurus for enhanced control over image output.

---
![Overrides the generation of img tags with Docusaurus](/img/v2/docusaurus_component.webp)

**TL;DR**

This article provides a simple solution for enabling lazy loading for images in Docusaurus to improve performance. It explains how to intercept the default rendering of `<img>` tags by customizing the `src/theme/MDXComponents.js` file. By adding a simple mapping, you can force all images to be lazy-loaded and even apply custom styles, without needing to create a complex component or plugin.

While searching for good tips & tricks about Docusaurus when the number of articles become important, I read that we need to pay attention to lazy load images and, indeed, by default all images are loaded when a blog post is first accessed.

In this article, we'll see how easily we can intercept the creation of the `<img>` tag when the Markdown content is converted to HTML.

This conversion occurs at two places: when you're surfing on your website or when you're generating a static version of it.

To do this, in fact, we don't need to create a component! We just need to add some lines of code in the `src/theme/MDXComponents.js` file. *If you need more than a couple of extra attributes — a wrapper `div`, custom CSS, a zoom effect — then a real component is the way to go; that's the subject of [Change how Docusaurus will create img tags](/blog/docusaurus-override-img).*

If you don't have that file yet, just create it.

> **Note:**
>
> The `// [...]` notation is there as a placeholder to show you that perhaps you'll have already some lines of code there. Don't delete it; just append the highlighted lines as shown below.

**src/theme/MDXComponents.js**

```javascript
import React from "react";

import MDXComponents from "@theme-original/MDXComponents";
// [...]

export default {
  // Reusing the default mapping
  ...MDXComponents,
  // highlight-start
  img: (props) => {
    const { loading, decoding, className, style, height, width, ...rest } = props;

    return (
      <img
        {...rest}
        // Make sure to keep "height='auto'" (so also disable width) as generated by Docusaurus
        // We shouldn't display the image at full size
        height='auto'
        width=''
        loading={loading || 'lazy'}
        decoding={decoding || 'async'}
        className={`${className || ''}`}

        // Example of how adding extra CSS
        style={{
          border: '20px solid #ccc',
          borderRadius: '6px',
          ...style,
        }}
      />
    );
  },
  // highlight-end
  // [...]
};
```

Once added to your `MDXComponents.js` file, just return to the browser; open any post and refresh the page. You'll see that images have now the `loading="lazy"` attribute (you can verify using the dev tools panel of your browser). If like in the example given here above, you've added some CSS style; you'll see it immediately.

Easy no?

Now, how do you make sure it stays true across two hundred articles? By checking it automatically: see [Running some checks on your Docusaurus images](/blog/docusaurus-check-images).
