#[solved] Importing images via relative path in MDX files

9 messages · Page 1 of 1 (latest)

oblique yoke
#

I tried the following below in a .mdx file, but it does not work. The error message and a screenshot of the file structure in my project are attached. In a normal .md file, I could reference images in the public directory, but I don't know if it's possible to put images and their associated pages in the same folder. Any help is appreciated!

---
title: Inline Images
description: A demonstration on inlining images in Astro with MDX files.
layout: ../layouts/MainLayout.astro
---

import polyGrid from "./poly-grid.svg";
import stackedPeaks from "./stacked-peaks.svg";

## Example Gallery

<img src={polyGrid} alt="A grid tiled by triangles of different shapes and sizes">
<img src={stackedPeaks} alt="A gradient of jagged color bands">
scenic eagle
# oblique yoke I tried the following below in a `.mdx` file, but it does not work. The error me...

Someone recently added this functionality to their plugin collection for MDX https://www.npmjs.com/package/astro-m2dx#relative-images

oblique yoke
oblique yoke
#

Works like a charm! I also like the default frontmatter value feature.

One thing that I noticed: if you have the frontmatter feature enabled, you include a field in the frontmatter that would have been covered by a default, and you include an image with a relative import, Astro throws an error. I can work around this, though.

Thanks for your help!

#

[solved] Importing images via relative path in MDX files

cunning laurel
#

One addendum: The overriding of frontmatter is working fine, but you have to be fairly careful with placing JSX components in your MDX, because in some situations the remark MDX extensions have some trouble recognizing the correct error, if there are any syntax errors. I haven't recorded any reproduction scenarios, yet, but I should start doing it. In all cases, where I had trouble so far, it was in my MDX, but the error messages were not always pointing to the problem.

dawn tide
#

You can also do this by lazy loading all images with a Glob and filepath, then using a wrapper component to lookup the image by filepath.

The astro.build website does this:

async function loadImage(lazyFile: () => any) {
  const { default: image } = await lazyFile();
  return image as ImageMetadata;
}

const images = import.meta.glob(["path/goes/here/*"]);


export async function allImages(
  pathname: string
): Promise<ImageMetadata | undefined> {
  return pathname in images ? loadImage(images[pathname]) : undefined;
}

#

I use it to ensure you get the aspect ratios:

---
import { Image } from '@astrojs/image/components';
import { allImages } from "@/data/images";

export interface Props {
  src: string;
  alt: string;
}
let { src, alt } = Astro.props as Props;

const meta = await allImages(src);

if (!meta) {
  throw Error(`Image not found: ${src}`);
}
const aspectRatio = Math.round(meta.height * 100 / meta.width);
---
<div class="image-wrapper">
  <div aria-hidden="true" style={`width: 100%; padding-bottom: ${aspectRatio}%;`}></div>
  <Image {...meta} src={meta} alt={alt ?? ""}/>
</div>
oblique yoke
#

I think I figured out the cause of the original problem. Despite <img> being a valid HTML void element, <img> tags must take the form <img … /> in .mdx files. Without the forward slash at the end, the error will occur. Hopefully this helps anyone else who encounters this issue.