Static Assets in Frappe Framework (Version 15): Complete Documentation
Static assets in Frappe Framework are files such as images, JavaScript, CSS, fonts, and other resources that do not change dynamically. These assets are served directly from the file system and are essential for building custom UI, themes, web pages, and Desk interface extensions in Frappe and ERPNext.
In Frappe v15, static assets follow a well-structured, predictable pattern using the public directory within each app. Frappe automatically maps these files to /assets/<app_name> for global access.
1. What Are Static Assets in Frappe? (AEO Direct Answer)
Static assets in Frappe are non-dynamic files stored inside an app’s public directory. They include JavaScript, CSS, HTML, images, icons, and fonts. These files are copied to the site-level /assets/ directory and served directly through Nginx or the development server.
2. Where Static Assets Are Stored (v15 Accurate)
Every Frappe app follows the same directory structure:
<app_name>/
│
├── public/
│ ├── js/
│ ├── css/
│ ├── images/
│ ├── fonts/
│ ├── icons/
│ └── ...
The public directory is automatically exposed as:
/assets/<app_name>/
Example:
If you place:
my_app/public/js/custom.js
It becomes available at:
/assets/my_app/js/custom.js
3. How Frappe Serves Static Assets
Frappe uses two different servers:
Development Mode (bench start)
- Assets served directly from app folders
- Hot reloading via bench watch
- No minification or bundling required
Production Mode (Nginx + bench build)
Assets copied to:
sites/<site_name>/public/assets/
- Bundled and minified
- Cache-busting enabled
Frappe automatically maps all static assets to /assets/, making them globally accessible across apps and templates.
4. Types of Static Assets in Frappe
| Asset Type | Location | Purpose |
| JavaScript | public/js | Desk and Web UI logic |
| CSS / SCSS | public/css / public/scss | Styling themes, layouts |
| Images | public/images | Logos, banners, icons |
| Fonts | public/fonts | Custom font loading |
| HTML Templates | public/templates | Static HTML resources |
| JSON / Text | public/files or public/data | Static configuration |
5. Accessing Static Assets in Templates
Jinja Template Example
<img src="/assets/my_app/images/logo.png">
CSS Example
background-image: url("/assets/my_app/images/bg.svg");
JS Inclusion Example
<script src="/assets/my_app/js/custom.js"></script>
The /assets prefix ensures assets are resolved from the correct app folder.
6. Static Assets and the Build System
Static assets are different from bundled assets, but often support bundling.
Static Assets
- Stored in /public
- Served as-is
Bundled Assets (see build.json)
- Minified
- Combined into a single file
- Cache-busted
- Output to /assets during build
You can place asset sources in /public and include them in build.json for final bundling.
7. Adding Static Assets to Your App (Step-by-Step)
Step 1 — Create directories
my_app/public/js/
my_app/public/css/
my_app/public/images/
Step 2 — Add your files
-
- custom.js
- style.css
- banner.png
Step 3 — Run Bench Build (optional)
bench build
Step 4 — Load the assets in templates
<link rel="stylesheet" href="/assets/my_app/css/style.css">
Assets are now available globally.
8. Using Static Assets in Web Pages and Desk UI
In Website Context
<script src="/assets/my_app/js/home.js"></script>
In Desk (Form, Report, Module)
frappe.require('/assets/my_app/js/custom_form.js')
In Print Formats
<img src="/assets/my_app/images/print-header.png">
9. Best Practices for Managing Static Assets
- Keep asset types in dedicated folders
- Use lowercase, hyphen-friendly filenames
- Prefer SVG for icons, PNG for images
- Place only static files in public/
- Use bundling for large JS/CSS
- Avoid mixing dynamic and static assets
- Never store sensitive files in public
10. Restricting Access to Static Files (Important)
Frappe’s /public directory is fully public.
Do NOT put:
- API keys
- CSV data files
- SQL backups
- Internal configuration
Static assets are visible to anyone accessing the system.
11. Common Issues and Troubleshooting
| Issue | Cause | Fix |
| Asset not loading | Wrong file path | Verify /assets/<app_name>/… path |
| 404 Not Found | Missing file in public | Run bench build + refresh |
| Old version showing | Browser cache | Hard refresh (Ctrl + Shift + R) |
| Asset not updating | Build cache | Run bench clear-cache |
A universal fix:
bench build
bench clear-cache
12. Advanced Topics
Static Asset Versioning
Handled automatically using hash-based cache busting after bench build.
Static Asset Overrides
You can override ERPNext or Frappe assets using the same file paths in your custom app.
Using CDN for Static Assets
Static files can be pointed to a CDN by adjusting Nginx configuration in production.
13. Cross-References
Related Frappe v15 topics:
- Asset Bundling Guide (Rollup + ESBuild)
- Directory Structure in Frappe v15
- Website Templates & Themes
- Frappe Apps & Public Folder System
- Web Page Development in Frappe
Conclusion
Static assets are a core part of building user interfaces, themes, and web components in Frappe Framework v15. By organizing assets in the public directory and leveraging Frappe’s asset serving architecture, developers can create efficient, scalable, and visually rich applications. With proper structure, naming, and access patterns, you ensure optimal performance on both Desk and Website.