Incorrect file structure in public/ directory causing broken assets

Loading

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)

  1. Always use process.env.PUBLIC_URL for public assets
  2. Place assets that shouldn’t be processed by Webpack in public/
  3. Keep index.html clean – no direct script/style tags

Vite

  1. Reference assets directly from /
  2. Use import for assets that need processing:
   import logo from './assets/logo.png'
  1. Place global assets in public/

Next.js

  1. Use public/ for static files
  2. For images, prefer next/image component
  3. Don’t use process.env.PUBLIC_URL – files are automatically served from root

Best Practices

  1. Keep it minimal: Only essential files should be in public/
  2. Organize by type: Group assets in subdirectories (images, fonts, etc.)
  3. Version files: For cache busting:
   <link href="/css/main.css?v=1.2.3" rel="stylesheet">
  1. Use environment variables: For dynamic paths in different environments
  2. Set proper permissions: Ensure files are readable (644 for files, 755 for directories)

Migration from Incorrect Structure

  1. Audit current public/ directory:
   tree public/ -L 3
  1. Move processed assets (like SCSS, JSX) out of public/
  2. Update all references to use correct paths
  3. Test locally before deploying:
   npm run build && serve -s build

Troubleshooting Checklist

  1. Verify file exists in built dist/ or build/ directory
  2. Check browser DevTools Network tab for 404 errors
  3. Ensure case sensitivity matches (Linux servers are case-sensitive)
  4. Confirm proper Content-Type headers are being served
  5. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *