docs/versioned_docs/version-8.5/assets-and-files.md
There are two ways to add an asset to your Redwood app:
web/public directory and reference it relative to your site's rootWhere possible, prefer the first strategy.
It lets Vite include the asset in the bundle when the file is small enough.
Let's say you want to show your app's logo in your Header component.
First, add your logo to the Header component's directory:
web/src/components/Header/
// highlight-next-line
├── logo.png
├── Header.js
├── Header.stories.js
└── Header.test.js
Then, in the Header component, import your logo as if it were code:
// highlight-next-line
import logo from './logo.png'
const Header = () => {
return (
<header>
// highlight-next-line
</header>
)
}
export default Header
If you're curious how this works, see the Vite docs on static asset handling.
web/public DirectoryYou can also add assets to the web/public directory, effectively adding static files to your app.
During dev and build, Redwood copies web/public's contents into web/dist.
Changes to
web/publicdon't hot-reload.
Again, because assets in this directory don't go through Vite, use this strategy sparingly, and mainly for assets like favicons, manifests, robots.txt, libraries incompatible with Vite, etc.
web/publicLet's say that you've added your logo and favicon to web/public:
web/public/
├── img/
│ └── logo.png
└── favicon.png
When you run yarn rw dev and yarn rw build, Redwood copies
web/public/img/logo.png to web/dist/img/logo.png and web/public/favicon.png to web/dist/favicon.png:
web/dist/
├── static/
│ ├── js/
│ └── css/
// highlight-start
├── img/
│ └── logo.png
└── favicon.png
// highlight-end
You can reference these files in your code without any special handling:
import { Head } from '@redwoodjs/web'
const Header = () => {
return (
<>
<Head>
// highlight-next-line
<link rel="icon" type="image/png" href="favicon.png" />
</Head>
// highlight-next-line
</>
)
}
export default Header
By default you can import and use SVG images like any other image asset.
// highlight-next-line
import svgIconSrc from '../mySvg.svg'
const Example = () => {
return (
<>
// highlight-next-line
</>
)
}
export default Example
Sometimes however, you might want more control over styling your SVGs - maybe you want to modify the stroke-width or fill color.
The easiest way to achieve this, is to make your SVGs a React component. Open up your SVG file, and drop in its contents into a component – for example:
import type { SVGProps } from "react"
export const CarIcon = (props: SVGProps) => {
return (
// 👇 content of your SVG file
<svg
// highlight-next-line
className="fill-blue-500" // 👈 you can use classes, like with tailwind
// highlight-next-line
stroke={props.strokeColor} // or adjust properties directly
// ...
If you needed to convert a whole library of SVGs into stylable (or animatable!) components, one easy way would be to use the SVGR cli
There are many different ways to peel this potato – it's all a search away – but if you're using the CSS @font-face rule, we have a quick tip for you:
web/
├── src
├── App.tsx
├── entry.client.tsx
├── index.css
├── ...
├── public
│ ├── favicon.png
│ ├── fonts
// highlight-next-line
│ │ └── RedwoodNeue.woff2
/* in e.g. index.css */
@font-face {
font-family: 'Redwood Neue';
/* 👇 it's a relative path */
// highlight-next-line
src: url('/fonts/RedwoodNeue.woff2')
format('woff2');
font-weight: 300;
font-style: italic;
ascent-override: 97%;
}