A well-organized public/
directory is crucial for ensuring assets load correctly in production. Common issues with incorrect structures include broken images, missing fonts, failed API requests, and routing problems.
Correct Public Directory Structure
public/
├── index.html # Main HTML template
├── favicon.ico # Favicon
├── robots.txt # SEO configuration
├── manifest.json # PWA manifest
├── assets/
│ ├── images/ # Global images
│ ├── fonts/ # Custom fonts
│ └── videos/ # Video files
└── locales/ # Translation files (if needed)
Common Problems and Solutions
1. Broken Image References
Incorrect:
<img src="/public/images/logo.png" />
Correct:
<!-- For Create React App -->
<img src={`${process.env.PUBLIC_URL}/images/logo.png`} />
<!-- For Vite -->
<img src="/images/logo.png" />
2. Missing Font Files
Incorrect CSS:
@font-face {
font-family: 'CustomFont';
src: url('/public/fonts/custom.woff2'); /* Won't work */
}
Correct CSS:
@font-face {
font-family: 'CustomFont';
/* CRA */
src: url(${process.env.PUBLIC_URL}/fonts/custom.woff2);
/* Vite */
src: url(/fonts/custom.woff2);
}
3. API Mock Files Not Found
Incorrect:
fetch('/public/api/mock-data.json')
Correct:
// CRA
fetch(`${process.env.PUBLIC_URL}/api/mock-data.json`)
// Vite
fetch('/api/mock-data.json')
Framework-Specific Guidance
Create React App (CRA)
- Always use
process.env.PUBLIC_URL
for public assets - Place assets that shouldn’t be processed by Webpack in
public/
- Keep
index.html
clean – no direct script/style tags
Vite
- Reference assets directly from
/
- Use import for assets that need processing:
import logo from './assets/logo.png'
- Place global assets in
public/
Next.js
- Use
public/
for static files - For images, prefer
next/image
component - Don’t use
process.env.PUBLIC_URL
– files are automatically served from root
Best Practices
- Keep it minimal: Only essential files should be in
public/
- Organize by type: Group assets in subdirectories (images, fonts, etc.)
- Version files: For cache busting:
<link href="/css/main.css?v=1.2.3" rel="stylesheet">
- Use environment variables: For dynamic paths in different environments
- Set proper permissions: Ensure files are readable (644 for files, 755 for directories)
Migration from Incorrect Structure
- Audit current
public/
directory:
tree public/ -L 3
- Move processed assets (like SCSS, JSX) out of
public/
- Update all references to use correct paths
- Test locally before deploying:
npm run build && serve -s build
Troubleshooting Checklist
- Verify file exists in built
dist/
orbuild/
directory - Check browser DevTools Network tab for 404 errors
- Ensure case sensitivity matches (Linux servers are case-sensitive)
- Confirm proper
Content-Type
headers are being served - Test with direct URL in browser:
http://localhost:3000/images/logo.png
By maintaining a proper public directory structure and referencing assets correctly, you’ll eliminate broken asset issues and ensure smooth deployments across all environments.