Conditionally load livereload.js only in development #2533
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The base template unconditionally loads livereload.js, causing connection timeouts to port 35729 in production environments. This introduces UI delays as browsers wait for the non-existent livereload server.
Changes
DevelopmentConfigDevelopment workflow with gulp-based livereload remains unchanged. Production, test, and other configs no longer load the script.
Original prompt
This section details on the original issue you should resolve
<issue_title>Unconditional livereload.js in base.jinja Causes UI Delays in ProductionConfig</issue_title>
<issue_description>In Specter Desktop v2.1.1, the base.jinja template unconditionally includes a livereload.js script, causing significant UI delays in production environments. The script requests http://:35729/livereload.js, which times out (1.3 minutes for login, 30 seconds for other pages) when no livereload server is running.
This occurs despite setting "livereload": false, dev: false, debug: false, and ProductionConfig in config.json, and enforcing Flask production mode (FLASK_DEBUG=0, WERKZEUG_DEBUG=0).
The issue stems from this line in templates/base.jinja:
"<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"></' + 'script>')<script>"
It lacks a conditional check (e.g., {% if app.config['LIVERELOAD'] %}), injecting the script into every page, even in ProductionConfig.
Steps to Reproduce
Install Specter Desktop v2.1.1 from source (git clone https://github.com/cryptoadvance/specter-desktop, git checkout v2.1.1, pip install .) in a Python 3.10 virtual environment.
Configure ~/.specter/config.json with:{
"config": "ProductionConfig",
"dev": false,
"livereload": false,
"debug": false,
"logfile": "/home/specter/.specter/specter.log",
"loglevel": "DEBUG",
...
}
Set up a systemd service with:ExecStart=/home/specter/.env/bin/python -m cryptoadvance.specter server --host 127.0.0.1 --config ProductionConfig
Environment="FLASK_ENV=production"
Environment="FLASK_DEBUG=0"
Environment="WERKZEUG_DEBUG=0"
Modify server.py to enforce:app.config['DEBUG'] = False
app.config['TESTING'] = False
app.config['LIVERELOAD'] = False
Start Specter (sudo systemctl start specter).
Open http://:25441 (e.g., http://raspibolt.local:25441) in a browser (e.g., Brave).
Check DevTools > Network: Observe a request to http://:35729/livereload.js that times out.
Measure page load times: ~1.3 minutes for login, ~30 seconds for other pages.
Expected Behavior
No livereload.js request in ProductionConfig when "livereload": false.
UI loads quickly (<5s for login, <2s for other pages).
base.jinja should conditionally include livereload.js only when app.config['LIVERELOAD'] or app.config['DEBUG'] is True (e.g., in DevelopmentConfig).
Actual Behavior
base.jinja unconditionally injects livereload.js, causing browser requests to http://:35729/livereload.js.
Requests time out (no server on :35729), delaying UI rendering.
Page load times: ~20s to 1.3 minutes (login), ~10-30 seconds (other pages).
Environment
OS: Ubuntu (RaspiBolt on Raspberry Pi 4)
Python: 3.10
Specter Version: v2.1.1 (installed from source, git checkout v2.1.1)
Virtual Environment: /home/specter/.env
Dependencies: sqlalchemy==1.4.50, flask-sqlalchemy==2.5.1, others per requirements.txt
Browser: Brave (also reproducible in Firefox)
Related Services: Bitcoin Knots 28.1 (127.0.0.1:8336), Electrs 0.10.7 (127.0.0.1:50001)
Logs
specter.log (excerpt):[2025-05-09 15:06:04,127] INFO in server: Configuration: cryptoadvance.specter.config.ProductionConfig
[2025-05-09 15:06:04,138] DEBUG in server: Flask DEBUG: False, LIVERELOAD: False
[2025-05-09 15:06:04,138] DEBUG in server: Loaded config: ProductionConfig
journalctl -u specter.service:
No errors; confirms ProductionConfig.
DevTools Network:
Request to http://raspibolt.local:35729/livereload.js with status 504 Gateway Timeout or stalled.
Full logs available: specter.log, specter_journal.log.
Workaround
Comment out the livereload.js script in base.jinja:
sudo nano /home/specter/.env/lib/python3.10/site-packages/cryptoadvance/specter/templates/base.jinja : line 16
Restart Specter:sudo systemctl restart specter
Result: No livereload.js requests, UI loads in <5s (login), <2s (other pages).
Suggested Fix
Add a conditional check in base.jinja:{% if app.config['LIVERELOAD'] %}
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"> {% endif %} Alternatively, remove the script entirely for ProductionConfig, as livereload is irrelevant in production. Additional Context Issue persisted despite extensive troubleshooting: Pinned dependencies to resolve SQLAlchemy errors (sqlalchemy==1.4.50). Simplified config.json to RaspiBolt-recommended settings. No livereload server runs on :35729 (netstat -tulnp | grep 35729 empty), confirming the request is client-driven. Reproducible on RaspiBolt setup with Knots and Electrs integration. Attachments specter.log: Server logs showing ProductionConfig and debug settings. specter_journal.log: Systemd logs for Specter service. DevTools screenshot: Showing ...