Contributing¶
Read our contribution guide at the organization level
Recommended Tools¶
Project Patterns¶
Web UI¶
The Web UI uses Vite as its build system.
The HTML pages used by the Web UI are found in
./src_assets/common/assets/web.EJS is used as a templating system for the pages (check
template_header.htmlandtemplate_header_main.html).The Style System is now powered by Tailwind CSS. (Bootstrap has been removed; a lightweight shim layer maps a few legacy classes like
btnandform-controlto Tailwind utilities for backward compatibility.)Icons are provided by Lucide and Simple Icons.
The JS framework used by the more interactive pages is Vus.js.
Routing Mode (History API)¶
The Vue router is configured with createWebHistory('/') (no hash fragment). The C++ config HTTP server provides a SPA fallback (getSpaEntry in src/confighttp.cpp) that serves index.html for any non-API, non-static route so deep links and refreshes work. When adding a new top‑level UI path under /, no backend change is needed unless it conflicts with existing static prefixes (/api, /assets, /covers, /images).
Tailwind CSS Integration¶
Tailwind utilities are compiled via PostCSS. The entry stylesheet src_assets/common/assets/web/styles/tailwind.css includes:
@tailwind base;
@tailwind components;
@tailwind utilities;
and is imported in main.js. The purge/content configuration lives in tailwind.config.js:
content: ['./src_assets/common/assets/web/**/*.{html,js,ts,vue}']
If you place Vue/HTML/TS files outside that tree, extend the glob so their class names are not purged. Tailwind preflight is enabled; any remaining Bootstrap-era markup should be updated to utilities. A shim layer in styles/tailwind.css defines legacy class aliases (.btn, variants, .form-control) to ease incremental refactors. Prefer replacing those with first-class Tailwind utilities over time. For dynamic class generation (string concatenation) add a safelist in tailwind.config.js instead of dummy elements.
Building¶
As of the release of LuminalShine, the standard build workflow has changed greatly from Sunshine and Vibeshine, with it now using clang with --fms-extensions to build the project. This allows MSVC-specific features to be implemented into LuminalShine without fully depending on MSVC for the build process.
Localization¶
LuminalShine and related NortheBridge Foundation projects are localized into into en (English, US).
This is the default language, and currently, there are no plans to localize it for other languages.
Extraction¶
Web UI¶
Sunshine uses Vue I18n for localizing the UI. The following is a simple example of how to use it.
Add the string to the
./src_assets/common/assets/web/public/assets/locale/en.jsonfile, in English.{ "index": { "welcome": "Hello, LuminalShine!" } }
[!NOTE] The JSON keys should be sorted alphabetically. You can use jsonabc to sort the keys.
[!WARNING] The below is for information only. Contributors should never include manually updated template files, or manually compiled language files in Pull Requests.
Strings are automatically extracted from the code to the locale/sunshine.po template file. The generated file is
used by CrowdIn to generate language specific template files. The file is generated using the
.github/workflows/localize.yml workflow and is run on any push event into the master branch. Jobs are only run if
any of the following paths are modified.
- 'src/**'
When testing locally it may be desirable to manually extract, initialize, update, and compile strings. Python is
required for this, along with the python dependencies in the ./scripts/requirements.txt file. Additionally,
xgettext must be installed.
Extract, initialize, and update
python ./scripts/_locale.py --extract --init --update
Compile
python ./scripts/_locale.py --compile
[!IMPORTANT] Due to the integration with CrowdIn, it is important to not include any extracted or compiled files in Pull Requests. The files are automatically generated and updated by the workflow. Once the PR is merged, the translations can take place on [CrowdIn][crowdin-url]. Once the translations are complete, a PR will be made to merge the translations into Sunshine.