Recommended Free Tools
For images used by Vue components, keep files under src and reference them in a Vue template or import them in the component. Vue’s Vite plugin turns template image references into imports, so Vite can include those files in the build and generate production URLs. Put an image in the project-root public directory instead when it needs a stable filename or must be copied unchanged.
Put component images in the source tree
For a known image used by a component, place the file in your source tree, commonly under src/assets. Reference it relative to the Vue file that uses it. The Vue plugin converts a Vue single-file component’s template asset reference into an import; Vite then processes the asset as part of the build graph. Referenced files commonly receive fingerprinted filenames in production.
As an Amazon Associate I earn from qualifying purchases.
<template>
<img src="../assets/hero.png" alt="A mountain landscape">
</template>
Adjust ../assets/hero.png to the actual location relative to the component. You can also import the asset explicitly in the component script and bind the resolved URL:
<script setup>
import heroUrl from '../assets/hero.png'
</script>
<template>
<img :src="heroUrl" alt="A mountain landscape">
</template>
Static imports give JavaScript a resolved public URL. CSS url() references are handled in a similar way. Common image, media, and font formats are recognized automatically; use a ?url import when you need to explicitly request URL handling for another file type. See Vite’s Static Asset Handling guide.
#1 Best Overall
Choose between src and public
| Need | Use | What happens |
|---|---|---|
| An image used by a Vue component should participate in the build | A template reference or JavaScript import from the source tree | The reference is analyzed and the asset is included in the build graph; output URLs can use generated filenames. |
| A stable filename or an unchanged copy | A file in the project-root public/ directory, referenced as /filename.png |
The file is served from the site root during development and copied to the output root without transformation. |
| A finite set of files selected dynamically in browser code | A statically analyzable new URL() pattern |
Vite can transform supported patterns into a map of imports. |
| An arbitrary path assembled at runtime or an SSR URL | A deployment-appropriate runtime URL strategy | Vite cannot bundle a path it cannot analyze; the documented new URL() pattern also has SSR limitations. |
Vite’s guidance is to prefer importing assets unless you need the guarantees of public. A file at public/logo.png is requested in the browser as /logo.png, not /public/logo.png. The public directory name is not part of the URL.
Handle dynamic image URLs carefully
Use a statically named asset
In browser-side code, a known file can be represented as a URL relative to the current module:
const imageUrl = new URL('./img.png', import.meta.url).href
Select from a finite set
When the possible images are known at build time, use a pattern Vite can statically analyze, such as a supported template-literal new URL() pattern. Vite can enumerate matching files and transform the expression into imports. Follow the pattern in the official asset guide; arbitrary runtime filesystem lookup is not available in a browser bundle.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Do not expect arbitrary runtime paths to be bundled
If the URL is computed from data in a way Vite cannot analyze, Vite leaves the expression as-is rather than discovering and bundling the target. The documented new URL(..., import.meta.url) approach also does not work as a general solution for SSR. For server-rendered applications or runtime-selected paths, use a URL strategy appropriate to the server and deployment rather than assuming a client-build asset lookup will work.
Make image URLs work under a deployment base path
If the site is deployed below a path such as /app/, configure Vite’s base for that deployment. During a production build, Vite adjusts imported asset URLs, CSS url() references, and HTML asset references to respect the configured base. The exact setting depends on the public path used by the host.
For a URL assembled in JavaScript that must begin with the configured base, use Vite’s exact expression import.meta.env.BASE_URL. Vite statically replaces it during the build:
const imageUrl = `${import.meta.env.BASE_URL}images/banner.png`
A relative base (./ or an empty string) is available when the final base path is unknown, but Vite documents a browser-support caveat involving import.meta. Check the Building for Production guide before relying on that mode.
Free tools Windows power users keep installed
One-click scans. No signup required.
Vite also treats index.html as source code and part of the module graph, and rebases its asset URLs during processing. For deployment behavior and the base setting, see Vite’s production build documentation and the getting started guide.
Best Value
Build and verify the production output
- Check the Vue plugin. Confirm the project’s Vite configuration enables the Vue plugin so single-file component template references are processed.
- Use a component-relative path. Verify the image path from the component’s location, not from the project root.
- Build the project. Run
vite buildor the project’s build script, commonlynpm run build, from the project directory. - Check the deployment base. If the app is hosted beneath a subpath, set Vite’s
baseto match and test the built site at that path. - Inspect the browser request. Confirm the image URL returns the file from the deployed build. For a public file, check that its path begins at the site root and omits
/public/.
For predictable deployment checks, test the production build under the actual host path, especially for GitHub Pages or another subpath deployment. A development-server success alone does not confirm that a root-relative URL will resolve on a nested deployment.
Inlining and output-size expectations
Vite may inline small assets as data URLs according to the configured assetsInlineLimit. The threshold depends on the installed Vite version and project configuration, so do not assume a fixed default without checking both. Larger or otherwise non-inlined assets are emitted as files. Inlining changes how an asset is represented in output; it does not make an unanalyzable runtime path bundle automatically.
Troubleshoot missing or broken images
- The image works in development but fails after deployment: check the configured
baseand whether the app is served from a subpath. Prefer imported assets or useimport.meta.env.BASE_URLfor a base-aware runtime URL. - A public image returns 404: confirm the file is under the project-root
publicdirectory and request it as/filename.png, not/public/filename.png. - A template image reference is not processed: confirm the Vue Vite plugin is enabled and the relative path is correct from the component file.
- A dynamically chosen image is missing from the build: Vite may not be able to analyze the runtime-computed path. Use a supported static pattern for a finite set, or load from a runtime URL source designed for the application.
- An asset unexpectedly appears as an encoded data URL: inspect the installed Vite version and
assetsInlineLimitconfiguration; inlining depends on that setting. - An SSR render has a broken
new URL()asset: the documented pattern has SSR limitations. Choose a server-compatible URL strategy rather than treating the browser-only transform as universal.
Or skip the browser setup
If you also need to capture a rendered page as an image while checking its deployed appearance, ScreenshotNeo provides a screenshot API. One GET request returns an image or PDF. Its cleanup can accept cookie or consent banners and remove 60+ known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. An MCP server exposes screenshot tools to AI agents, including Claude, Cursor, and other MCP clients.
Example cURL request (replace the example URL with your deployed page and use your API key):
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. ScreenshotNeo offers 1,000 screenshots a month free with no card; paid plans start at $5 for 3,000 screenshots. Learn about ScreenshotNeo or sign up for 1,000 free screenshots a month with no card.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




