Skip to content

Conversation

@luis-c465
Copy link
Contributor

This PR adds PWA functionality for the web version of feishin.

The PWA functionality allows the app to be downloaded and added to the desktop as a normal desktop app, creating its own window when opened. Though it will use the browser that the user downloaded the PWA from to run the web app.

image image

Why not just use the normal desktop app

In my case there are a couple or reasons:

  1. When using the Linux desktop app on my laptop running Fedora 42 audio playback on the desktop app with both available playback methods consumes much more power and CPU than expected. Often pegging a thread on my computer, draining battery life. Chances are this is an issue on my part, though since the web version exists I would rather use that version.
  2. Since the desktop app is using electron to run a Chromium browser for the app to work. Effectively running the app in a browser with additional features. To save on both memory and CPU I would rather run the app in a browser I already have opened. Even if I lose some features because of it.
  3. With the PWA sharing resources from the browser it also shares extensions. Notably there is an extension which can automatically pause the music when another sound in the browser is playing. This is quite convenient, and would otherwise be much more difficult to do with the music being played from a separately installed desktop app.

The changes

To add the PWA a development dependency is added vite-plugin-pwa.
This plugin handles creating both the manifest file for the PWA, and the service worker which allows the servers assets (HTML, CSS, JS) to be cached on the device.

When the web version is built, the plugin will create both the manifest file and the service worker file and place them in the assets' directory.

As a final change, since the PWA manifest needs both icons and a screenshot preview of the app, some icons and media screenshots are included in the final build.

Notes

  • The PWA will not work nor show up when the web version is being run in development mode. Unfortunately the production web handles showing public assets slightly differently than the development version due to a lack of the public folder.
  • Finally, thank you for making this awesome music player, been using daily for a year lol. Easily the best self-hostable one I have found so far.

@vercel
Copy link

vercel bot commented Oct 7, 2025

@luis-c465 is attempting to deploy a commit to the jeffvli's projects Team on Vercel.

A member of the Team first needs to authorize it.

@vercel
Copy link

vercel bot commented Oct 8, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
feishin Ready Ready Preview Comment Oct 11, 2025 2:03pm

Copy link
Collaborator

@kgarner7 kgarner7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. The service worker is served at /sw.js, which is not correct in the nginx/docker configuration (assets/sw.js)
  2. Please fix your lint errors.

Copy link
Collaborator

@kgarner7 kgarner7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. The problem appears to be the way that index.html is generated, where it still tries to load from ./sw.js

<script id="vite-plugin-pwa:inline-sw">if('serviceWorker' in navigator) {window.addEventListener('load', () => {navigator.serviceWorker.register('./sw.js', { scope: '/' })})}</script>

It looks like you should change https://vite.dev/config/shared-options.html#base (./assets).
To test this, I recommend using the docker build and making sure it works

docker build -t feishin .
docker run -d --name feishin  -p 9180:9180 feishin

(You may need to do this over https, as service worker registration is very picky)

@luis-c465
Copy link
Contributor Author

TLDR, I tried for a long time to get the VitePWA plugin working while the sw.js and manifest are in the assets directory though could not get it to work. Instead, make a one line change to the nginx template config to allow files to be served from the root.


I had initially tried to get the PWA working while putting the manifest and the sw in the assets directory though that lead to 2 issues:

  1. Then the service worker is under assets/sw.js which means at maximum it can only have a scope of assets meaning it can no longer cache the index.html resulting in the PWA not working if not connected to the internet. (This could only be fixed if the nginx config is changed to return a specific service worker allowed header)
  2. The vite PWA plugin seems to be largely built around the assumption that the manifest and sw.js will be placed at the root of the project. If not the configs for both have to be changed, and during tested led to a large amount of issues of the paths being different between the two. Even after finding a configuration that worked the workerbox script seems to be hardcoded to load from the root of the project, resulting in some files not being cached as expected.

While the 2 issues above could be fixed by finicking with configuration till it works, it may be better to make an exception for both of those files and allow them to live at the root of the site.

To allow that I removed a remove the try_files $uri $uri/ /index.html =404; at the / location in the nginx template file. Removing it allows the manifest and sw files to be correctly served at the root.

Testing this with docker the app is working as expected and no errors are shown in the console, even when the network is disabled in the developer console.
image

@kgarner7
Copy link
Collaborator

Ah, I actually apologize greatly; your prior fix did work (I hadn't pulled it). That has a minimal set of changes, so it's preferable.

@luis-c465
Copy link
Contributor Author

@kgarner7 I reverted the commit to put the sw and manifest at the root.

@kgarner7 kgarner7 merged commit d3a986e into jeffvli:development Oct 11, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants