Do what you love
Shares

Extending Default Props in Next.js

Last updated: Jul 6, 2024

In some cases, you need to add to the existing prop type definition for a component. In this article, we'll take a quick look at just how easy that is to do.

Why extend props?

In my case, I needed to add a prop to the default props for the Image component in Next.js. I was building out this blog using MDX and wanted to be able to pass in some class names to add to the component. The easiest way to do this was to extend the props that Image expects.

NOTE: I found a better solution to the problem of passing an Image component into MDX and didn't go with this solution, but it does demonstrate how to extend default props quite nicely.

The Error

The original error that prompted this was generated by trying to pass the Image component directly into MDX. This should work but it gives this error:

Cannot access Image.propTypes on the server. You cannot dot into a client module from a server component.

I went off some Google workarounds I found and created a wrapped Image component to pass in that works. Then I wanted to extend it with some additional styling and went down this route. (See NOTE above about discarding this solution for a better one later.)

The Solution

I created an MDX variable that I can pass in as a component to the MDX renderer.

import React, { ReactNode } from 'react';
import Image, { ImageProps } from 'next/image';

export type ExtendedImageProps = ImageProps & {
  classes: string;
};

export const MDX = {
  Image: (props: ExtendedImageProps) => (
    <Image {...props} className={props.classes} alt={props.alt} />
  ),
};

Then add it to my components list and pass into MDXRemote:

import { MDX } from '@ui/mdx';

const components = {
  MDX,
  Link,
};

...
    <MDXRemote source={content} components={components} />
...

As you can see, I can now use this component within MDX and pass in some Tailwind classes to add to the Image component (and others). I use this for this blog post and all others like this:

(MDX code stored in database)

<MDX.Image classes="rounded-lg" src="/images/blog/dev.jpg" width="5184" height="3456" alt="Image of code." />

And the result is this image:

Image of code.

That's it! I'm sure this isn't the final solution I will try with MDX, but it did give me a lesson in extending default prop types. Maybe it will be useful to you as well. Happy coding!