2026-01-24 22:59:20 +00:00
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { VitePWA } from 'vite-plugin-pwa'
import path from 'path'
// https://vite.dev/config/
export default defineConfig ( {
plugins : [
vue ( ) ,
VitePWA ( {
registerType : 'autoUpdate' ,
2026-03-06 01:11:00 +00:00
includeAssets : [ 'assets/icon/favico-black-v2.svg' , 'assets/icon/pwa-64x64-v2.png' , 'assets/icon/pwa-192x192-v2.png' , 'assets/icon/pwa-512x512-v2.png' , 'assets/icon/maskable-icon-512x512-v2.png' , 'assets/icon/apple-touch-icon-180x180-v2.png' , 'favicon-v2.ico' ] ,
2026-01-24 22:59:20 +00:00
manifest : {
name : 'Archipelago' ,
short_name : 'Archipelago' ,
description : 'Your sovereign personal server' ,
theme_color : '#000000' ,
background_color : '#000000' ,
display : 'standalone' ,
2026-02-18 13:48:45 +00:00
display_override : [ 'standalone' , 'minimal-ui' ] ,
2026-01-24 22:59:20 +00:00
orientation : 'any' ,
scope : '/' ,
start_url : '/' ,
2026-02-18 13:48:45 +00:00
id : '/' ,
2026-02-01 18:46:35 +00:00
categories : [ 'productivity' , 'utilities' ] ,
prefer_related_applications : false ,
2026-01-24 22:59:20 +00:00
icons : [
2026-03-06 01:11:00 +00:00
{ src : '/assets/icon/pwa-64x64-v2.png' , sizes : '64x64' , type : 'image/png' , purpose : 'any' } ,
{ src : '/assets/icon/pwa-192x192-v2.png' , sizes : '192x192' , type : 'image/png' , purpose : 'any' } ,
{ src : '/assets/icon/pwa-512x512-v2.png' , sizes : '512x512' , type : 'image/png' , purpose : 'any' } ,
{ src : '/assets/icon/maskable-icon-512x512-v2.png' , sizes : '512x512' , type : 'image/png' , purpose : 'maskable' }
2026-01-24 22:59:20 +00:00
] ,
shortcuts : [
2026-03-06 01:11:00 +00:00
{ name : 'Dashboard' , short_name : 'Dashboard' , description : 'Open the dashboard' , url : '/dashboard' , icons : [ { src : '/assets/icon/pwa-192x192-v2.png' , sizes : '192x192' } ] } ,
{ name : 'My Apps' , short_name : 'Apps' , description : 'Manage your apps' , url : '/dashboard/apps' , icons : [ { src : '/assets/icon/pwa-192x192-v2.png' , sizes : '192x192' } ] } ,
{ name : 'App Store' , short_name : 'Store' , description : 'Browse and install apps' , url : '/dashboard/marketplace' , icons : [ { src : '/assets/icon/pwa-192x192-v2.png' , sizes : '192x192' } ] }
2026-01-24 22:59:20 +00:00
]
} ,
workbox : {
2026-03-05 08:24:56 +00:00
navigateFallbackDenylist : [ /^\/app\// , /^\/rpc\// , /^\/ws/ , /^\/aiui\// ] ,
2026-01-24 22:59:20 +00:00
globPatterns : [ '**/*.{js,css,html,ico,png,svg,jpg,jpeg,mp4,webp}' ] ,
globIgnores : [
'**/*-backup-*.mp4' ,
'**/*-1.47mb.mp4' ,
'**/bg-*.mp4' , // Exclude large background videos from precache
2026-03-14 17:12:41 +00:00
'**/video-intro*.mp4' , // Exclude all intro video variants from precache
2026-03-08 00:02:37 +00:00
'**/assets/icon/**' , // Icons are in includeAssets — don't duplicate in glob precache
2026-01-24 22:59:20 +00:00
] ,
2026-03-14 17:12:41 +00:00
maximumFileSizeToCacheInBytes : 10 * 1024 * 1024 , // 10MB limit
2026-01-24 22:59:20 +00:00
skipWaiting : false , // Wait for user to accept update
clientsClaim : false , // Don't claim clients immediately
runtimeCaching : [
{
urlPattern : /^https:\/\/fonts\.googleapis\.com\/.*/i ,
handler : 'CacheFirst' ,
options : {
cacheName : 'google-fonts-cache' ,
expiration : {
maxEntries : 10 ,
maxAgeSeconds : 60 * 60 * 24 * 365 // 1 year
} ,
cacheableResponse : {
statuses : [ 0 , 200 ]
}
}
} ,
{
urlPattern : /^https:\/\/fonts\.gstatic\.com\/.*/i ,
handler : 'CacheFirst' ,
options : {
cacheName : 'gstatic-fonts-cache' ,
expiration : {
maxEntries : 10 ,
maxAgeSeconds : 60 * 60 * 24 * 365 // 1 year
} ,
cacheableResponse : {
statuses : [ 0 , 200 ]
}
}
} ,
{
urlPattern : /\/rpc\/v1\/.*/i ,
handler : 'NetworkFirst' ,
options : {
cacheName : 'api-cache' ,
expiration : {
maxEntries : 50 ,
maxAgeSeconds : 60 * 5 // 5 minutes
} ,
networkTimeoutSeconds : 10
}
} ,
{
urlPattern : /\/assets\/.*/i ,
handler : 'CacheFirst' ,
options : {
2026-03-06 01:11:00 +00:00
cacheName : 'assets-cache-v2' ,
2026-01-24 22:59:20 +00:00
expiration : {
maxEntries : 100 ,
maxAgeSeconds : 60 * 60 * 24 * 30 // 30 days
}
}
}
]
} ,
devOptions : {
enabled : true ,
type : 'module'
}
} )
] ,
resolve : {
alias : {
'@' : path . resolve ( __dirname , './src' )
}
} ,
server : {
port : 8100 ,
proxy : {
'/rpc/v1' : {
target : process.env.BACKEND_URL || 'http://localhost:5959' ,
changeOrigin : true ,
secure : false ,
} ,
'/ws' : {
target : process.env.BACKEND_URL || 'http://localhost:5959' ,
ws : true ,
changeOrigin : true ,
secure : false ,
rewrite : ( path ) = > path , // Don't rewrite the path
2026-01-27 23:06:18 +00:00
timeout : 0 , // No timeout for WebSocket connections
2026-01-24 22:59:20 +00:00
} ,
'/public' : {
target : process.env.BACKEND_URL || 'http://localhost:5959' ,
changeOrigin : true ,
secure : false ,
} ,
'/rest' : {
target : process.env.BACKEND_URL || 'http://localhost:5959' ,
changeOrigin : true ,
secure : false ,
} ,
2026-03-05 08:24:56 +00:00
'/app/filebrowser' : {
target : 'http://192.168.1.228' ,
changeOrigin : true ,
secure : false ,
} ,
2026-01-24 22:59:20 +00:00
} ,
} ,
build : {
// Output to dist for Docker builds, or to ../web/dist/neode-ui for local development
outDir : process.env.DOCKER_BUILD === 'true' ? 'dist' : '../web/dist/neode-ui' ,
emptyOutDir : true ,
} ,
} )