Skip to content

Conditionally load livereload.js only in development#2533

Draft
Copilot wants to merge 5 commits intomasterfrom
copilot/fix-livereload-ui-delays
Draft

Conditionally load livereload.js only in development#2533
Copilot wants to merge 5 commits intomasterfrom
copilot/fix-livereload-ui-delays

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 5, 2026

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

  • base.jinja: Wrap livereload.js script tag with config check for DevelopmentConfig
  • test_livereload_conditional.py: Verify script inclusion behavior across configs
{% if config.SPECTER_CONFIGURATION_CLASS_FULLNAME and 'DevelopmentConfig' in config.SPECTER_CONFIGURATION_CLASS_FULLNAME %}
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"></' + 'script>')</script>
{% endif %}

Development 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 ...
- Fixes #2495 --- ✨ Let Copilot coding agent [set things up for you](https://github.com/cryptoadvance/specter-desktop/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.

@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 5, 2026

Deploy Preview for specter-desktop-docs canceled.

Name Link
🔨 Latest commit 4b46c13
🔍 Latest deploy log https://app.netlify.com/projects/specter-desktop-docs/deploys/6984422e6e928f0008fb6116

Copilot AI and others added 3 commits February 5, 2026 07:07
Co-authored-by: k9ert <117085+k9ert@users.noreply.github.com>
Co-authored-by: k9ert <117085+k9ert@users.noreply.github.com>
Co-authored-by: k9ert <117085+k9ert@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix unconditional inclusion of livereload.js in base.jinja Conditionally load livereload.js only in development Feb 5, 2026
Copilot AI requested a review from k9ert February 5, 2026 07:11
Copy link
Copy Markdown
Contributor

@al-munazzim al-munazzim left a comment

Choose a reason for hiding this comment

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

✅ LGTM - simple and correct fix.

The unconditional livereload.js was causing significant delays in production (1+ minute timeouts). Wrapping it in a DevelopmentConfig check is the right approach.

Minor note: Could also check config.DEBUG or a dedicated LIVERELOAD config flag, but checking the config class name works fine.

@k9ert
Copy link
Copy Markdown
Contributor

k9ert commented Apr 17, 2026

@copilot resolve the merge conflicts in this pull request

- Accepted master's simpler config.DEBUG check instead of SPECTER_CONFIGURATION_CLASS_FULLNAME
- Removed test_livereload_conditional.py since the fix is already in master via PR #2543

Co-authored-by: k9ert <117085+k9ert@users.noreply.github.com>
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 17, 2026

Deploy Preview for specter-desktop-docs canceled.

Name Link
🔨 Latest commit 4f57fe2
🔍 Latest deploy log https://app.netlify.com/projects/specter-desktop-docs/deploys/69e2869f29fbfc00084932c7

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 17, 2026

@copilot resolve the merge conflicts in this pull request

Merge conflict resolved in commit 4f57fe2.

The conflict in base.jinja was resolved by accepting master's implementation which uses {% if config.DEBUG %} instead of the more complex configuration class name check. Master branch already fixed the same issue via PR #2543 using Flask's built-in DEBUG config, which is simpler and more idiomatic.

Also removed tests/test_livereload_conditional.py since the fix is now in master.

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.

Unconditional livereload.js in base.jinja Causes UI Delays in ProductionConfig

3 participants