Jash Naik
Jash Naik

Reputation: 21

How to dynamically import images in astro.js framework components(react specifically)?

I have a json file containing an array of object's in following format

[
  {
    name: "foo",
    image: "/src/assets/default.webp"
  },
  {
    name: "Jonas",
    image: "https://..."
  }
]

Then in my astro file , I am simply importing the json , iterating over it and passing the data to my react components

i.e

---
import data from "../data.json"
---

data.map((e) => {
  <Reactcomponent data={data} client:load/>
})

Reactcomponent.jsx

export default function React component({data}) {
  return (
    <>
      <p>{data.name}</p>
      <img src={data.image} alt="..." />
    </>
  )
}

It works just fine in dev mode but in production I have had no luck so far 😕

I can see the images in my dist/_astro folder but they've been renamed and when I inspect the image's in build mode their path remains the same /src/assets/imgname

But in the build there is no src or assets folder and the images also have been renamed

Tbh I am not even sure that the images i am seeing in the dist/_astro folder have something to do with them being used in json

I have read the documentation and it only shows examples of static imports , i have heard about a vite plugin that uses the import() function but it has its own issues , is there any "natural" way to do it or available API for it

Upvotes: 1

Views: 1833

Answers (2)

J&#225;nos Ill&#233;s
J&#225;nos Ill&#233;s

Reputation: 23

This is the relevant part of Astro's documentation: https://docs.astro.build/en/guides/images/#src-vs-public

If you want to keep using <img> then put your images in the public directory. If you want to keep them in src directory then you will need something that copies them over into your build directory, like Astro's Image component.

You can also abuse nodejs and Astro's Dynamic routes for this. Here is a rough outline how would that work in a src/pages/images/[path].jpg.ts file:

export const GET: APIRoute = async ({ params }) => {
  const path = params.path as string;
  let data;
  if (!existsSync(path)) {
     // error handling
  } else {
    data = await readFile(path);
  }

  return new Response(data, {
    headers: { "Content-Type": "image/jpeg" },
  });
}

export function getStaticPaths() {
  return YOUR_JSON_DATA.map((record) => ({ params: { path: record.image } }));
}

Upvotes: 0

Bryce Russell
Bryce Russell

Reputation: 1360

You can follow this recipe in the docs for a guide on how to Dynamically Import Images

Upvotes: -1

Related Questions