shuding / nextra

Simple, powerful and flexible site generation framework with everything you love from Next.js.
https://nextra.site
MIT License
11.71k stars 1.27k forks source link

`staticImage` prevents custom MDX `img` component #1821

Closed jukrb0x closed 1 year ago

jukrb0x commented 1 year ago

Use case

I am customizing my blog theme, and an Image component comes into play when I am trying to overwrite MDX components like this:

const Image = ({ src, alt, ...props }: ComponentProps<'img'>): ReactElement => {
    return (
        // the custom `next/image` wrapped component
    )
}
const useComponents = (): Components => {
    const { config } = useBlogContext();
    return {
        h1: H1,
        h2: (props) => <HeadingLink tag="h2" { ...props } />,
// ...
        img: Image,
        ...config.components
    };
};

this doesn't work since staticImage: true, the reason is nextra would replace each regular <img> to a wrapped static imported next/image component in a mdx plugin: https://github.com/shuding/nextra/blob/main/packages/nextra/src/mdx-plugins/static-image.ts#L45

image

To work around this, I need to set staticImage: false and then customize my Image component, but the thing is the static imports are broken:

image

I am still researching a way to make it work, I wouldn't like to make a modeled nextra for my project.

Expected behaviour

the best idea is to keep staticImage: true but be able to customize the mdx component

additional

  1. the other way is having the static imports work without the framework staticImage logic
  2. ability to have to add mdx plugin from user's side

take a deep look into this problem, if I custom an Image MDX component:

next/image requires a width and height for a image for a remote URL, the component will see the URL passed in as a stringy remote source (fill property is not desired in my case, width and height are necessary), nextra will replace the source to be locally imported, that's fine as an mdx plugin (framework-wise).

now I am not sure if this problem can be solved from the user-side.

dimaMachina commented 1 year ago

Please share a reproduction repo and I'll take a look at why it doesn’t work for you

jukrb0x commented 1 year ago

Please share a reproduction repo and I'll take a look at why it doesn’t work for you

@B2o5T Thanks for responding!

Here's the reproduction branch for this issue: https://github.com/jukrb0x/wh0.is/tree/nextra/reprod-static-image

The live codesandbox: https://codesandbox.io/p/github/jukrb0x/wh0.is/nextra/reprod-static-image

The images starting with / will be fine since they are put in /public directory, the use-case for me is the relative local path like ./some-image.jpg, and next/image will see the stringy URL as a remote source, which will ask for a width and height (fill doesn't apply for my case)... this seems to be an obstacle for constructing an MDX component.

There are 2 problems in this case:

  1. The image on the home page will be rendered correctly but with a hardcoded width and height.
  2. The image in relative path ./xxx.jpg is messed up on any post page.
dimaMachina commented 1 year ago

you can temporarily patch this line https://github.com/shuding/nextra/blob/d23a655581c99a82bf1ece0a80981f20a0c031b1/packages/nextra/src/mdx-plugins/static-image.ts#L74 to name: 'img', so staticImage: true and custom img component will works and you will receive follow data as props

image

Also I will think about how it could be implemented in nextra via a new option or something like this

jukrb0x commented 1 year ago

Great! Thanks so much, I am looking forward to a framework-wise solution in future releases.