Skip to content
Jonathan Sharpe edited this page Aug 24, 2024 · 3 revisions

Client side

Vite offers several ways to handle images in the client code; for example, you can just import an image from a relative path in web/src/ and use the result as the src attribute of the img:

import reactLogo from "../assets/react.svg";

function ReactLogo() {
  return (
    <a href="https://react.dev" target="_blank" rel="noreferrer">
      <img src={reactLogo} className="logo react" alt="React logo" />
    </a>
  );
}

export default ReactLogo;

and this image will be bundled and either inlined or placed in api/static/assets/ with the other client-side build outputs.

For details and alternatives, see Static Asset Handling in the Vite documentation.

Server side

If you'd like to serve images directly from the server instead, you can use Express's own static middleware. For example, if you create a new directory api/images/ containing your images, you can add the following to api/app.js:

import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

// ...

const __dirname = fileURLToPath(dirname(import.meta.url));

app.use("/images", express.static(join(__dirname, "images")));

Now you can use a relative path to the image just like the API routes:

export default function SomeComponent() {
  return <img src="/images/image.png" />;
}

In this case you should also add "/images" to the list of routes that are proxied in development mode, see web/vite.config.js:

    server: {
      port: process.env.PORT,
      proxy: {
        "/api": `http://localhost:${apiPort}`,
        "/healthz": `http://localhost:${apiPort}`,
+       "/images": `http://localhost:${apiPort}`,
      },
    },

However note there is no particular performance improvement here; the images imported in the client code are also served statically by Express in production mode, via the existing clientRouter defined in api/utils/middleware.js.

Clone this wiki locally