A modern vnStat dashboard with a React frontend and a small PHP backend.
- Page entry:
index.html - Data API:
api/traffic.php - Frontend source:
src/ - Internal PHP helpers:
app/ - Themes:
themes/light,themes/dark
vnstatinstalled and already collecting traffic data- PHP-enabled web server
- Node.js and npm only if you want to rebuild the frontend bundle
- Put the repository inside your web root.
- Edit
config.php. - If you changed frontend code, build the React bundle:
npm install
npm run build- Open
index.htmlin the browser, or use the site root if your web server maps it there.
Runtime responsibilities:
- Nginx serves
index.html,dist/, andthemes/ - PHP-FPM executes
api/traffic.php vnstatis called by PHP to read traffic data
Build responsibilities:
- Use Node.js and npm only when you run
npm installandnpm run build - After build, deploy the generated
dist/folder together with the PHP files
Example deployment path:
/var/www/vnstat/
That directory should contain at least:
index.htmlapi/app/dist/themes/lang/config.php
server {
listen 443 ssl http2;
server_name vnstat.example.com;
root /var/www/vnstat;
index index.html;
charset utf-8;
ssl_certificate /root/.acme.sh/example.com_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/example.com_ecc/example.com.key;
ssl_client_certificate /root/.acme.sh/example.com_ecc/ca.cer;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
location / {
try_files $uri $uri/ /index.html?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2)$ {
expires 7d;
access_log off;
}
}If you want HTTP to HTTPS redirection, add a separate port 80 server block.
Any normal PHP-FPM setup is fine. PHP 7.4 may work, but a newer supported PHP version is recommended.
What PHP-FPM must be able to access:
api/traffic.phpconfig.phpapp/lang/- the
vnstatbinary configured inconfig.php
If you see 403 Forbidden, check permissions before anything else.
Typical safe permissions:
sudo find /var/www/vnstat -type d -exec chmod 755 {} \;
sudo find /var/www/vnstat -type f -exec chmod 644 {} \;
sudo chown -R www-data:www-data /var/www/vnstatAlso make sure the parent directories are searchable by Nginx:
ls -ld /var /var/www /var/www/vnstatThe web server user needs execute permission on each directory in that path.
Typical production flow:
cd /var/www/vnstat
npm install
npm run build
sudo systemctl reload nginx
sudo systemctl reload php7.4-fpmIf you build elsewhere, copy the built dist/ folder to the server together with the PHP files.
Main options live in config.php:
locale: locale used for date formattinglanguage: UI language, for examplecn,en,nlifaceList: list of vnStat interfacesifaceTitle: display names for interfacesvnstatBin: path to thevnstatbinarydataDir: fallback directory for dump filesbyteNotation: force a preferred unit or leavenulldefaultStyle: default theme, currentlylightpageList: available views,h,d,m,sstyleList: available themes, currentlylight,dark
The UI still uses query parameters:
if: interfacepage:s,h,d,mstyle:lightordark
Example:
/index.html?if=eth0&page=d&style=light
Use index.html for page links. The project does not include an index.php entry point.
The app data endpoint is:
/api/traffic.php?if=eth0&page=d&style=light&format=app
The bootstrap endpoint used before the app renders is:
/api/traffic.php?if=eth0&page=d&style=light&format=bootstrap
Frontend commands:
npm install
npm run buildThe repository already includes built assets in dist/, but if you change anything in src/, rebuild before deployment.
- Switch interfaces and time ranges without reloading the page; browser back/forward restores the view.
- Refresh traffic manually. “Last fetched” is the browser fetch time, not the vnStat collection time. Failed refreshes retain the last successful data for the same view.
- The theme is remembered locally; an explicit
styleURL parameter takes priority. - Toggle incoming/outgoing series in the chart; sort detail rows and export them as CSV with raw KB counters.
- Missing vnStat or dump data returns HTTP 503 with a JSON error. A valid empty dataset shows an empty state.
- Relative
dataDirpaths resolve from the project root. Old samples use “Latest” labels instead of claiming they are current.
Validation commands:
npm test
npm run buildTests require Node.js and PHP. The build also checks TypeScript. For a local preview, build the frontend and run php -S 127.0.0.1:8080 -t . from the project root; actual traffic requires your configured vnStat binary or dump files.
If opening the site returns 403, check these items in order:
rootpoints to the project directory that containsindex.html.- Nginx uses
index index.html;instead of onlyindex.php. - The
location /block includestry_files $uri $uri/ /index.html?$query_string;. - The project files and parent directories are readable and searchable by the Nginx user.
dist/manifest.jsonanddist/assets/exist after build.- PHP-FPM socket path is correct, for example
/var/run/php/php7.4-fpm.sock.
Useful checks:
ls -lah /var/www/vnstat
ls -lah /var/www/vnstat/dist
php -l /var/www/vnstat/api/traffic.php
sudo nginx -tIf /index.html works but / returns 403, check the Nginx index and try_files configuration.
Check that vnStat works for the configured interface:
vnstat --json -i eth0If the page still shows old behavior after deployment, refresh PHP opcache or restart PHP-FPM / the web server.
Many modern systems no longer use eth0. Verify the actual name:
vnstat --iflistThen update ifaceList and ifaceTitle in config.php.
This project continues to use the original GPL licensing terms from the upstream vnStat PHP frontend. See COPYING.