| name | frontend-development |
| description | Provides frontend development guidelines for Nette. Use when working with Vite, SCSS, JavaScript/TypeScript, Nette Assets ({asset} tag, asset mapping), ESLint with @nette/eslint-plugin, Naja AJAX library, frontend entry points, npm packages in Nette context, Tailwind CSS with Latte templates, nette-forms npm package, HMR, build commands (npm run dev/build), or passing data from PHP to JavaScript. |
Frontend Development
Frontend built with modern tooling and seamlessly integrated with Nette backend through Nette Assets.
See the Nette Assets reference for asset management.
See the Vite integration guide for build configuration.
Technology Stack
- Build system: Vite with TypeScript support
- JavaScript: ES Modules (ESM) with
"type": "module" in package.json
- Styling: SCSS with modular component architecture
- Asset integration: Nette Assets for PHP-frontend bridge
- Admin framework: Bootstrap for rapid interface development
- Code quality: ESLint with @nette/eslint-plugin
- Forms: Nette Forms with progressive enhancement
Asset Architecture Strategy
Source vs Built Assets separation:
- Development assets:
assets/ directory with source files (SCSS, TypeScript, images)
- Production assets:
www/assets/ with optimized, versioned files for browsers
Coding Standards
- Use single quotes for strings unless containing apostrophes (CSS, SCSS, JavaScript)
Entry Point Decision Matrix
Use separate entry points when:
- Different user contexts with distinct dependencies (frontend vs admin)
- Bundle size optimization is critical
Example strategy:
import './css/front.scss';
import './js/components/product-gallery.js';
import 'bootstrap/dist/css/bootstrap.css';
import './css/admin.scss';
Organization Patterns
File-per-component approach:
assets/js/
├── components/
│ ├── product-form.js ← Reusable form component
│ ├── image-gallery.js ← Product image viewer
├── pages/
│ ├── blog.css ← Page-specific enhancements
│ └── checkout.css ← Multi-step checkout flow
└── utils/
├── ajax.js ← AJAX utilities
└── validation.js ← Form validation helpers
Nette Assets Integration Patterns
Basic asset loading
{* Loads complete bundle with all dependencies *}
{asset 'front.js'}
Configuration
assets:
mapping:
default:
type: vite
devServer: true # Enable HMR in debug mode
Data Flow from Backend to Frontend
Passing data to JavaScript:
{* In template *}
<script>
window.appConfig = {
apiUrl: {$baseUrl . '/api'},
userId: {$user->isLoggedIn() ? $user->getId() : null},
locale: {$locale},
csrfToken: {$csrfToken}
};
</script>
{asset 'front.js'}
Latte automatically applies context-sensitive escaping – values inside <script> are JSON-encoded, so strings get quoted and null stays null.
const { apiUrl, userId, csrfToken } = window.appConfig;
fetch(`${apiUrl}/user-data`, {
headers: { 'X-CSRF-Token': csrfToken }
});
Naja (AJAX Library)
Naja is the standard AJAX library for Nette – it handles snippet redrawing, form submissions, and history integration:
npm install naja
import naja from 'naja';
naja.initialize();
Naja automatically intercepts links and forms with the ajax CSS class and handles snippet updates from the server. See Naja documentation for configuration and extensions.
Nette Forms Integration
Requires nette-forms npm package:
npm install nette-forms
Standard enhancement pattern:
import netteForms from 'nette-forms';
netteForms.initOnLoad();
ESLint Configuration
npm install --save-dev @nette/eslint-plugin eslint
Basic configuration with recommended rules:
import nette from '@nette/eslint-plugin';
import { defineConfig } from 'eslint/config';
export default defineConfig([
{
extends: [nette.configs.recommended],
},
]);
Linting JavaScript in Latte templates:
npm install --save-dev eslint-plugin-html
import nette from '@nette/eslint-plugin';
import pluginHtml from 'eslint-plugin-html';
import { defineConfig } from 'eslint/config';
export default defineConfig([
{
extends: [nette.configs.recommended],
},
{
files: ['app/**/*.latte'],
plugins: {
html: pluginHtml,
},
processor: '@nette/latte',
},
]);
This allows ESLint to check JavaScript inside <script> tags with Latte variables:
<script>
let name = {$name};
</script>
TypeScript support:
npm install --save-dev typescript typescript-eslint
import nette from '@nette/eslint-plugin/typescript';
export default defineConfig([
{
extends: [nette.configs.typescript],
},
]);
Custom rules:
@nette/no-this-in-arrow-except - Prevents this binding issues in arrow functions
@nette/prefer-line-comments - Enforces // over /* */ for single-line comments
Tailwind CSS Integration
When using Tailwind CSS, configure it to scan Latte templates for class names:
@import 'tailwindcss';
@source '../app/**/*.latte';
Essential Commands
npm run dev
npm run build
npm run build:dev
npm run lint
npm run lint:fix
Online Documentation
For detailed information, use WebFetch on these URLs:
- Assets – Nette Assets documentation
- Naja – AJAX library for Nette