Resolve missing assets in Create React App with SASS by ensuring your image paths are relative to the CSS file rather than the JavaScript component, and verifying that webpack handles static files correctly. This common issue stems from how the build system resolves URLs in stylesheets versus module imports, requiring a specific adjustment in your asset references to restore visibility.
Understanding Asset Resolution in CRA
Create React App uses webpack under the hood to bundle your application. When you import an image directly in a JavaScript file using
import logo from './logo.png', webpack treats it as a module, processes it, and returns the correct hashed URL. However, when you reference an image inside a SASS or CSS file, the resolution logic changes. The browser interprets the path in the
url() directive relative to the location of the stylesheet itself, not the component rendering it.
If you use an absolute path like
/src/assets/image.png in your SCSS, the browser looks for that file at the root of your domain. Since your app is likely hosted at
/ or a subdirectory, this path often results in a 404 error because the file does not exist at the server root. The solution involves shifting from absolute filesystem paths to relative paths or leveraging webpack's built-in handling for static assets.
The Relative Path Strategy
The most robust way to fix missing images in SASS is to use relative paths that account for the directory structure. If your SCSS file is located in
src/components/Header/header.scss and your image is in
src/assets/logo.png, you must navigate up one directory level before entering the assets folder. Your CSS rule should look like this:
.header {
background-image: url('../assets/logo.png');
}
This tells the compiler to look in the parent directory of the current SCSS file, then into the
assets folder. This method works reliably because it mirrors the actual file structure on disk. It ensures that whether you are running the development server or building for production, the relative distance between the style sheet and the image remains constant.
Configuring Static Files Correctly
In older versions of Create React App, developers often placed static assets in the
public folder and referenced them with absolute paths starting with
/. While this still works for HTML and JavaScript, it can cause confusion when mixed with SASS. If you move your images to the
public folder, you must ensure your SASS files reference them correctly. For example, if
logo.png is in
public/images/, your SCSS should use:
.hero {
background-image: url('/images/logo.png');
}
However, mixing strategies is discouraged. The modern best practice for Create React App is to keep all source code, including images used by components, within the
src directory. This allows webpack to optimize, hash, and bundle these assets alongside your code, reducing network requests and preventing broken links due to deployment path mismatches.
Handling SVGs and Complex Assets
SVG files sometimes behave differently depending on how they are imported. If you are using inline SVGs via
url() in SASS, ensure the file extension is correct. Webpack’s default loader configuration supports PNG, JPG, GIF, and SVG out of the box. If you encounter issues specifically with SVGs, verify that your project has not been ejected or modified in a way that disables the file loader. For standard Create React App projects, no extra configuration is needed beyond placing the file in
src and referencing it relatively.
For more complex scenarios involving variable management in SASS, you might find related guidance useful. You can check our guide on
importing SCSS variables into another file to ensure your asset paths are stored cleanly in variables for easier maintenance. This prevents hardcoding paths throughout multiple stylesheets and reduces the chance of typos causing missing asset errors.
Debugging Persistent Issues
If you have adjusted your paths and the images still do not appear, perform a clean rebuild. Sometimes, the development server caches old module resolutions. Stop the server and run
npm start again. Clear your browser cache as well, as the browser may be holding onto a previous 404 response.
Check the Network tab in your browser’s developer tools. Look for the request made by the stylesheet. If the status is 404, inspect the exact URL being requested. Compare this URL to the relative path you defined. Remember that the base URL for resources in a stylesheet is the directory containing that stylesheet. If your path starts with
./, it is relative to the SCSS file. If it starts with
/, it is relative to the web root.
Additionally, ensure that your file names match exactly, including case sensitivity. Linux-based servers and some CI/CD pipelines are case-sensitive.
Logo.PNG is not the same as
logo.png. Windows and macOS file systems are generally case-insensitive, which can lead to working locally but failing in production if the repository enforces strict casing.
Alternative Import Methods
While
url() in SASS is standard, you can also import images as modules in JavaScript and pass them as inline styles. This approach bypasses SASS resolution entirely. In your component:
import logo from './logo.png';
const MyComponent = () => (
url(${logo}) }} />
);
This method guarantees that webpack resolves the asset correctly because it happens in the JavaScript module context. It is particularly useful when the image path depends on dynamic data or props. However, for static design elements, keeping the logic in SASS with relative paths is cleaner and more maintainable.
Frequently Asked Questions
Why do my images work in JS but not in SASS?
JavaScript imports treat assets as modules processed by webpack, while SASS url() directives are resolved relative to the stylesheet's location. This difference in resolution context causes absolute paths to fail in CSS even if they work in JSX. Always use relative paths in SASS to align with the file structure.
Can I use the public folder for all images?
Yes, you can place images in the public folder and reference them with absolute paths like /images/pic.png in SASS. However, this prevents webpack from optimizing or hashing the files, which can impact performance and caching strategies. It is better to keep assets in src for modern builds.
What if I get a 404 error after deploying to Netlify or Vercel?
Deployment platforms often serve the app from the root directory. If your SASS uses absolute paths starting with /, the browser looks for files at the domain root, which may not contain your app's assets. Switching to relative paths within the src folder ensures the build process generates correct links regardless of the hosting environment.
How do I handle background images in CSS modules?
CSS Modules scope class names but do not change how url() resolves paths. You still need to use relative paths from the CSS file to the image. Alternatively, you can import the image in the JS file and use it in the style object, which avoids path resolution issues in the CSS file entirely.
Does ejecting Create React App change asset handling?
Ejecting exposes the webpack configuration, allowing you to customize loaders. However, the default behavior for resolving static assets remains similar. You may need to manually configure file-loader or asset modules if you have custom requirements, but for standard images, relative paths in SASS continue to work as expected.