Enable the `require-await` ESLint rule. Async functions without `await`
are just regular functions with extra overhead — marking them `async`
adds implicit Promise wrapping, can hide missing `return` statements,
and misleads readers into expecting asynchronous behavior where there is
none.
While fixing the violations, I removed unnecessary `async` keywords from
source files and from various test callbacks that never used `await`.
This migrates the Weather module from client-side fetching to use the
server-side centralized HTTPFetcher (introduced in #4016), following the
same pattern as the Calendar and Newsfeed modules.
## Motivation
This brings consistent error handling and better maintainability and
completes the refactoring effort to centralize HTTP error handling
across all default modules.
Migrating to server-side providers with HTTPFetcher brings:
- **Centralized error handling**: Inherits smart retry strategies
(401/403, 429, 5xx backoff) and timeout handling (30s)
- **Consistency**: Same architecture as Calendar and Newsfeed modules
- **Security**: Possibility to hide API keys/secrets from client-side
- **Performance**: Reduced API calls in multi-client setups - one server
fetch instead of one per client
- **Enabling possible future features**: e.g. server-side caching, rate
limit monitoring, and data sharing with third-party modules
## Changes
- All 10 weather providers now use HTTPFetcher for server-side fetching
- Consistent error handling like Calendar and Newsfeed modules
## Breaking Changes
None. Existing configurations continue to work.
## Testing
To ensure proper functionality, I obtained API keys and credentials for
all providers that require them. I configured all 10 providers in a
carousel setup and tested each one individually. Screenshots for each
provider are attached below demonstrating their working state.
I even requested developer access from the Tempest/WeatherFlow team to
properly test this provider.
**Comprehensive test coverage**: A major advantage of the server-side
architecture is the ability to thoroughly test providers with unit tests
using real API response snapshots. Don't be alarmed by the many lines
added in this PR - they are primarily test files and real-data mocks
that ensure provider reliability.
## Review Notes
I know this is an enormous change - I've been working on this for quite
some time. Unfortunately, breaking it into smaller incremental PRs
wasn't feasible due to the interdependencies between providers and the
shared architecture.
Given the scope, it's nearly impossible to manually review every change.
To ensure quality, I've used both CodeRabbit and GitHub Copilot to
review the code multiple times in my fork, and both provided extensive
and valuable feedback. Most importantly, my test setup with all 10
providers working successfully is very encouraging.
## Related
Part of the HTTPFetcher migration #4016.
## Screenshots
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-06-54"
src="https://github.com/user-attachments/assets/2139f4d2-2a9b-4e49-8d0a-e4436983ed6e"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-02"
src="https://github.com/user-attachments/assets/880f7ce2-4e44-42d5-bfe4-5ce475cca7c2"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-07"
src="https://github.com/user-attachments/assets/abd89933-fe03-40ab-8a7c-41ae1ff99255"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-12"
src="https://github.com/user-attachments/assets/22225852-f0a9-4d33-87ab-0733ba30fad3"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-17"
src="https://github.com/user-attachments/assets/7a7192a5-f237-4060-85d7-6f50b9bef5af"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-22"
src="https://github.com/user-attachments/assets/df84d9f1-e531-4995-8da8-d6f2601b6a08"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-27"
src="https://github.com/user-attachments/assets/4cf391ac-db43-4b52-95f4-f5eadc5ea34d"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-32"
src="https://github.com/user-attachments/assets/8dd8e688-d47f-4815-87f6-7f2630f15d58"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-37"
src="https://github.com/user-attachments/assets/ee84a8bc-6b35-405a-b311-88658d9268dd"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-42"
src="https://github.com/user-attachments/assets/f941f341-453f-4d4d-a8d9-6b9158eb2681"
/>
Provider "Weather API" added later:
<img width="1910" height="1080" alt="Ekrankopio de 2026-02-15 19-39-06"
src="https://github.com/user-attachments/assets/3f0c8ba3-105c-4f90-8b2e-3a1be543d3d2"
/>
and centralize and optimize replace regex.
Another follow up to #4029
With this PR you can use secrets in urls in browser modules if you use
the cors proxy.
## Loading `config.js`
### Previously
Loaded on server-side in `app.js` and in the browser by including
`config.js` in `index.html`. The web server has an endpoint `/config`
providing the content of server loaded `config.js`.
### Now
Loaded only on server-side in `app.js`. The browser loads the content
using the web server endpoint `/config`. So the server has control what
to provide to the clients.
Loading the `config.js` was moved to `Utils.js` so that
`check_config.js` can use the same functions.
## Using environment variables in `config.js`
### Previously
Environment variables were not allowed in `config.js`. The workaround
was to create a `config.js.template` with curly braced bash variables
allowed. While starting the app the `config.js.template` was converted
via `envsub` into a `config.js`.
### Now
Curly braced bash variables are allowed in `config.js`. Because only the
server loads `config.js` he can substitute the variables while loading.
## Secrets in MagicMirror²
To be honest, this is a mess.
### Previously
All content defined in the `config` directory was reachable from the
browser. Everyone with access to the site could see all stuff defined in
the configuration e.g. using the url http://ip:8080/config. This
included api keys and other secrets.
So sharing a MagicMirror² url to others or running MagicMirror² without
authentication as public website was not possible.
### Now
With this PR we add (beta) functionality to protect sensitive data. This
is only possible for modules running with a `node_helper`. For modules
running in the browser only (e.g. default `weather` module), there is no
way to hide data (per construction). This does not mean, that every
module with `node_helper` is safe, e.g. the default `calendar` module is
not safe because it uses the calendar url's as sort of id and sends them
to the client.
For adding more security you have to set `hideConfigSecrets: true` in
`config.js`. With this:
- `config/config.env` is not deliverd to the browser
- the contents of environment variables beginning with `SECRET_` are not
published to the clients
This is a first step to protect sensitive data and you can at least
protect some secrets.
This migrates the Newsfeed module to use the centralized HTTPFetcher
class (introduced in #4016), following the same pattern as the Calendar
module.
This continues the refactoring effort to centralize HTTP error handling
across all modules.
## Changes
**NewsfeedFetcher:**
- Refactored from function constructor to ES6 class (like the calendar
module in #3959)
- Replaced manual fetch() + timer handling with HTTPFetcher composition
- Uses structured error objects with translation keys
- Inherits smart retry strategies (401/403, 429, 5xx backoff)
- Inherits timeout handling (30s) and AbortController
**node_helper.js:**
- Updated error handler to use `errorInfo.translationKey`
- Simplified property access (`fetcher.url`, `fetcher.items`)
**Cleanup:**
- Removed `js/module_functions.js` (`scheduleTimer` no longer needed)
- Removed `#module_functions` import from package.json
## Related
Part of the HTTPFetcher migration effort started in #4016.
Next candidate: Weather module (client-side → server-side migration).
This is another change to cleanup structure, already mentioned in
https://github.com/MagicMirrorOrg/MagicMirror/pull/4019#issuecomment-3792953018
After separating default and 3rd-party modules this PR moves the
`custom.css` from the mm-owned directory `css` into user owned directory
`config`.
It has a built-in function which moves the `css/custom.css` to the new
location `config/custom.css` (if the target not exists).
Let me know if there's a majority in favor of this change.
Since the project's inception, I've missed a clear separation between
default and third-party modules.
This increases complexity within the project (exclude `modules`, but not
`modules/default`), but the mixed use is particularly problematic in
Docker setups.
Therefore, with this pull request, I'm moving the default modules to a
different directory.
~~I've chosen `default/modules`, but I'm not bothered about it;
`defaultmodules` or something similar would work just as well.~~
Changed to `defaultmodules`.
Let me know if there's a majority in favor of this change.
## Summary
PR [#3976](https://github.com/MagicMirrorOrg/MagicMirror/pull/3976)
introduced smart HTTP error handling for the Calendar module. This PR
extracts that HTTP logic into a central `HTTPFetcher` class.
Calendar is the first module to use it. Follow-up PRs would migrate
Newsfeed and maybe even Weather.
**Before this change:**
- ❌ Each module had to implemented its own `fetch()` calls
- ❌ No centralized retry logic or backoff strategies
- ❌ No timeout handling for hanging requests
- ❌ Error detection relied on fragile string parsing
**What this PR adds:**
- ✅ Unified HTTPFetcher class with intelligent retry strategies
- ✅ Modern AbortController with configurable timeout (default 30s)
- ✅ Proper undici Agent for self-signed certificates
- ✅ Structured error objects with translation keys
- ✅ Calendar module migrated as first consumer
- ✅ Comprehensive unit tests with msw (Mock Service Worker)
## Architecture
**Before - Decentralized HTTP handling:**
```
Calendar Module Newsfeed Module Weather Module
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ fetch() own │ │ fetch() own │ │ fetch() own │
│ retry logic │ │ basic error │ │ no retry │
│ error parse │ │ handling │ │ client-side │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
└───────────────────────┴───────────────────────┘
▼
External APIs
```
**After - Centralized with HTTPFetcher:**
```
┌─────────────────────────────────────────────────────┐
│ HTTPFetcher │
│ • Unified retry strategies (401/403, 429, 5xx) │
│ • AbortController timeout (30s) │
│ • Structured errors with translation keys │
│ • undici Agent for self-signed certs │
└────────────┬──────────────┬──────────────┬──────────┘
│ │ │
┌───────▼───────┐ ┌────▼─────┐ ┌──────▼──────┐
│ Calendar │ │ Newsfeed │ │ Weather │
│ ✅ This PR │ │ future │ │ future │
└───────────────┘ └──────────┘ └─────────────┘
│ │ │
└──────────────┴──────────────┘
▼
External APIs
```
## Complexity Considerations
**Does HTTPFetcher add complexity?**
Even if it may look more complex, it actually **reduces overall
complexity**:
- **Calendar already has this logic** (PR #3976) - we're extracting, not
adding
- **Alternative is worse:** Each module implementing own logic = 3× the
code
- **Better testability:** 443 lines of tests once vs. duplicating tests
for each module
- **Standards-based:** Retry-After is RFC 7231, not custom logic
## Future Benefits
**Weather migration (future PR):**
Moving Weather from client-side to server-side will enable:
- **Same robust error handling** - Weather gets 429 rate-limiting, 5xx
backoff for free
- **Simpler architecture** - No proxy layer needed
Moving the weather modules from client-side to server-side will be a big
undertaking, but I think it's a good strategy. Even if we only move the
calendar and newsfeed to the new HTTP fetcher and leave the weather as
it is, this PR still makes sense, I think.
## Breaking Changes
**None**
----
I am eager to hear your opinion on this 🙂
In #3407 we already talked about unifying them.
- Create SVG favicon (better then png)
- Replace base64 placeholder in index.html with SVG favicon
- Update electron.js to use SVG favicon instead of mm2.png
- Add favicon.svg to server static routes
- Remove mm2.png
If an error occurs during startup, we request system information from
the user. The problem is that this information is displayed too late,
for example, if the configuration check fails.
My initial idea was to use `await
Utils.logSystemInformation(global.version);`, but this increased the
startup time.
Therefore, the function is now called in a subprocess. This approach
provides the information in all cases and does not increase the startup
time.
The config checker previously only allowed Node.js globals, but since
the config file runs also in the browser context, users should be able
to access browser APIs like `document` or `window` when needed.
This was incorrectly flagged as an error by the `no-undef` ESLint rule.
The fix adds browser globals to the allowed globals in the linter
config.
Fixes#3990.
and remove CHANGELOG.md logic.
This is my attempt to create a draft release instead of editing a
changelog, see discussion on discord.
Logic:
- new github workflow `.github/workflows/release-notes.yaml`
- runs with every push on `develop` (so after PR's are merged)
- collects the commits on `develop` which are newer than the latest tag
- searches the commit messages for keywords defined in an array and
group the messages into categories (this is a first shot, we will update
this ...)
- creates markdown content
- looks for an untagged and unpublished draft release with name
`unreleased`, if it exists, it will be deleted
- creates an untagged and unpublished draft release with name
`unreleased` with markdown content created above
Example created on my fork (this caused having `MagicMirrorOrg` in the
PR-Links):
<img width="952" height="1804" alt="grafik"
src="https://github.com/user-attachments/assets/38687bed-f5da-4dcb-93eb-242c317769df"
/>
Please review this PR, it is a draft release at the moment because I got
problems in my fork where I tested this: The created draft release is
not visible at the moment (they are visible via api). AFAIS this is a
queue problem on GitHub, maybe I flooded their queue while testing ...
So I will test this tomorrow again before removing `draft` here.
1. Convert CalendarFetcher from legacy constructor function pattern to
ES6 class (which simplifies future migration from CommonJS to ES
modules).
2. Implement targeted HTTP error handling with smart retry strategies
for common calendar feed issues:
- 401/403: Extended retry delay (5× interval, min 30 min)
- 429: Retry-After header parsing with 15 min fallback
- 5xx: Exponential backoff (2^count, max 3 retries)
- 4xx: Extended retry (2× interval, min 15 min)
- Add serverErrorCount tracking for exponential backoff
- Error messages now include specific HTTP status codes and calculated
retry delays for better debugging and user feedback
Previously, CalendarFetcher did not respond appropriately to HTTP
errors, continuing to hammer endpoints without backoff, potentially
overloading servers and triggering rate limits. This refactoring
implements respectful retry strategies that adapt to server responses
and reduce unnecessary load.
Maybe we could later centralize the HTTP error handling and use it for
weather and newsfeed as well.
The PR was inspired by having worked on the calendar fetcher for
MMM-CalendarExt2, where there was already better error handling.
### 1. Replace `XMLHttpRequest` with the modern `fetch` API for loading
translation files
#### Changes
- **translator.js**: Use `fetch` with `async/await` instead of XHR
callbacks
- **loader.js**: Align URL handling and add error handling (follow-up to
fetch migration)
- **Tests**: Update infrastructure for `fetch` compatibility
#### Benefits
- Modern standard API
- Cleaner, more readable code
- Better error handling and fallback mechanisms
### 2. Migrate e2e tests to Playwright
This wasn't originally planned for this PR, but is related. While
investigating suspicious log entries which surfaced after the fetch
migration I kept running into JSDOM’s limitations. That pushed me to
migrate the E2E suite to Playwright instead.
#### Changes
- switch e2e harness to Playwright (`tests/e2e/helpers/global-setup.js`)
- rewrite specs to use Playwright locators + shared `expectTextContent`
- install Chromium via `npx playwright install --with-deps` in CI
#### Benefits
- much closer to real browser behaviour
- and no more fighting JSDOM’s quirks
## CI Log Suppression
**Two-level approach for clean test output:**
1. **Suppress debug/info logs**: Call `logger.setLogLevel("ERROR")` in
CI to hide verbose logging
2. **Suppress intentional error logs**: Set `mmTestMode` flag and check
it before logging errors that are part of test assertions (e.g., testing
error handling in `git_helper.js` and `server_functions.js`)
This keeps CI output clean and makes genuine failures immediately
visible, while preserving full logging for local development.
**Before:** 1348 log lines with verbose debug/info output
**After:** 168 log clean lines with only test results
## Calendar Symbol Test Stability
Convert the calendar symbol test from external URL (`calendarlabs.com`)
to existing local mock file (`12_events.ics`). This eliminates CI
timeouts caused by external dependencies and improves test reliability.
The test still validates the same symbol array feature but now runs
faster and deterministically without network dependencies.
This is a big change, but I think it's a good move, as `vitest` is much
more modern than `jest`.
I'm excited about the UI watch feature (run `npm run test:ui`), for
example - it's really helpful and saves time when debugging tests. I had
to adjust a few tests because they had time related issues, but
basically we are now testing the same things - even a bit better and
less flaky (I hope).
What do you think?
## Description
This PR adds a new `server:watch` script that runs MagicMirror² in
server-only mode with automatic restart and browser reload capabilities.
Particularly helpful for:
- **Developers** who need to see changes immediately without manual
restarts.
- **Users setting up their mirror** who make many changes to `config.js`
or `custom.css` and need quick feedback.
### What it does
When you run `npm run server:watch`, the watcher monitors files you
specify in `config.watchTargets`. Whenever a monitored file changes:
1. The server automatically restarts
2. Waits for the port to become available
3. Sends a reload notification to all connected browsers via Socket.io
4. Browsers automatically refresh to show the changes
This creates a seamless development experience where you can edit code,
save, and see the results within seconds.
### Implementation highlights
**Zero dependencies:** Uses only Node.js built-ins (`fs.watch`,
`child_process.spawn`, `net`, `http`) - no nodemon or external watchers
needed.
**Smart file watching:** Monitors parent directories instead of files
directly to handle atomic writes from modern editors (VSCode, etc.) that
create temporary files during save operations.
**Port management:** Waits for the old server instance to fully release
the port before starting a new one, preventing "port already in use"
errors.
### Configuration
Users explicitly define which files to monitor in their `config.js`:
```js
let config = {
watchTargets: [
"config/config.js",
"css/custom.css",
"modules/MMM-MyModule/MMM-MyModule.js",
"modules/MMM-MyModule/node_helper.js"
],
// ... rest of config
};
```
This explicit approach keeps the implementation simple (~260 lines)
while giving users full control over what triggers restarts. If
`watchTargets` is empty or undefined, the watcher starts but monitors
nothing, logging a clear warning message.
---
**Note:** This PR description has been updated to reflect the final
implementation. During the review process, we refined the approach
multiple times based on feedback.
---------
Co-authored-by: Jboucly <contact@jboucly.fr>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
- Combine file existence and permission checks with better error
messages
- Replace thrown exceptions with clean error output (no stack traces)
- Support custom module positions by changing strict validation to
warnings
- Add missing process.exit(1) after validation errors
Users now see clear, actionable error messages without stack traces, and
custom region configurations work correctly.
## example before
```bash
$ npm run start
> magicmirror@2.34.0-develop start
> node --run start:x11
[2025-10-22 17:56:06.303] [LOG] Starting MagicMirror: v2.34.0-develop
[2025-10-22 17:56:06.304] [LOG] Loading config ...
[2025-10-22 17:56:06.304] [LOG] config template file not exists, no envsubst
[2025-10-22 17:56:06.356] [ERROR] File not found: /home/kristjan/MagicMirror/config/config.js
No config file present!
[2025-10-22 17:56:06.356] [ERROR] [checkconfig] Error: Error: ENOENT: no such file or directory, access '/home/kristjan/MagicMirror/config/config.js'
No permission to access config file!
at checkConfigFile (/home/kristjan/MagicMirror/js/check_config.js:43:9)
at Object.<anonymous> (/home/kristjan/MagicMirror/js/check_config.js:138:2)
at Module._compile (node:internal/modules/cjs/loader:1714:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1848:10)
at Module.load (node:internal/modules/cjs/loader:1448:32)
at Module._load (node:internal/modules/cjs/loader:1270:12)
at c._load (node:electron/js2c/node_init:2:17993)
at TracingChannel.traceSync (node:diagnostics_channel:322:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:244:24)
at Module.require (node:internal/modules/cjs/loader:1470:12)
at require (node:internal/modules/helpers:147:16)
at loadConfig (/home/kristjan/MagicMirror/js/app.js:126:3)
at App.start (/home/kristjan/MagicMirror/js/app.js:291:18)
at Object.<anonymous> (/home/kristjan/MagicMirror/js/electron.js:228:7)
at Module._compile (node:internal/modules/cjs/loader:1714:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1848:10)
```
## example after
```bash
$ npm run start
> magicmirror@2.34.0-develop start
> node --run start:x11
[2025-10-22 21:33:27.930] [LOG] Starting MagicMirror: v2.34.0-develop
[2025-10-22 21:33:27.931] [LOG] Loading config ...
[2025-10-22 21:33:27.931] [LOG] config template file not exists, no envsubst
[2025-10-22 21:33:27.985] [ERROR] [check_config] File not found: /home/kristjan/MagicMirror/config/config.js
```
This fixes security issue
[CVE-2023-42282](https://github.com/advisories/GHSA-78xj-cgh5-2h22),
which is not very likely to be exploitable in MagicMirror² setups, but
still should be fixed.
The [express-ipfilter](https://www.npmjs.com/package/express-ipfilter)
package depends on the obviously unmaintained
[ip](https://github.com/indutny/node-ip) package, which has known
security vulnerabilities. Since no fix is available, this commit
replaces both dependencies with a custom middleware using the better
maintained [ipaddr.js](https://www.npmjs.com/package/ipaddr.js) library.
Changes:
- Add new `js/ip_access_control.js` with lightweight middleware
- Remove `express-ipfilter` dependency, add `ipaddr.js`
- Update `js/server.js` to use new middleware
- In addition, I have formulated the descriptions of the corresponding
tests a little more clearly.
Adding a rule to the config checker config so that unexpected commas in
the middle of arrays (reported in issue #3910) are better detected.
Two commas in a row inside the modules array create an empty entry
(`undefined`). JavaScript accepts that syntax, but MagicMirror would
later try to load that “module” and fail.
Alternatively, we could filter out undefined entries, but with this PR,
the user receives a clear message indicating where the error lies, can
easily fix it, and thus has a cleaner configuration.
## Before
```
[2025-10-10 19:33:30.874] [INFO] Checking config file /home/kristjan/MagicMirror/config/config.js ...
[2025-10-10 19:33:30.944] [INFO] Your configuration file doesn't contain syntax errors :)
[2025-10-10 19:33:30.945] [INFO] Checking modules structure configuration ...
[2025-10-10 19:33:31.027] [ERROR] This module configuration contains errors:
undefinedmust be object
```
## After
```
[2025-10-10 19:41:20.030] [INFO] Checking config file /home/kristjan/MagicMirror/config/config.js ...
[2025-10-10 19:41:20.107] [ERROR] Your configuration file contains syntax errors :(
Line 91 column 1: Unexpected comma in middle of array.
```
- removes the external unmaintained `module-alias` dependency ->
reducing complexity and risk
- introduces a small internal alias mechanism for `logger` and
`node_helper`
- preserves backward compatibility for existing 3rd‑party modules
- should simplify a future ESM migration of MagicMirror
I'm confident that it shouldn't cause any problems, but we could also
consider including it in the release after next. What do you think?
This PR is inspired by PR #2934 - so thanks to @thesebas! 🙇😃
Having repeatedly seen that users are unaware of the meaning of the
EADDRINUSE error message (see, for example, this [forum
thread](https://forum.magicmirror.builders/topic/19871/update-package-list/5)),
I thought we should intercept this message and provide clearer output.
This may help users identify the cause of the problem more quickly
themselves.
## before
```
[2025-09-13 09:54:32.903] [LOG] Starting MagicMirror: v2.33.0-develop
...
[2025-09-13 09:54:33.533] [LOG] Starting server on port 8080 ...
[2025-09-13 09:54:33.537] [WARN] You're using a full whitelist configuration to allow for all IPs
[2025-09-13 09:54:33.568] [ERROR] Whoops! There was an uncaught exception...
[2025-09-13 09:54:33.574] [ERROR] Error: listen EADDRINUSE: address already in use 0.0.0.0:8080
at Server.setupListenHandle [as _listen2] (node:net:1940:16)
at listenInCluster (node:net:1997:12)
at node:net:2206:7
at process.processTicksAndRejections (node:internal/process/task_queues:90:21) {
code: 'EADDRINUSE',
errno: -98,
syscall: 'listen',
address: '0.0.0.0',
port: 8080
}
[2025-09-13 09:54:33.574] [ERROR] MagicMirror² will not quit, but it might be a good idea to check why this happened. Maybe no internet connection?
[2025-09-13 09:54:33.574] [ERROR] If you think this really is an issue, please open an issue on GitHub: https://github.com/MagicMirrorOrg/MagicMirror/issues
[2025-09-13 09:54:35.235] [INFO]
#### System Information ####
...
```
## after
```
[2025-09-13 09:53:20.151] [LOG] Starting MagicMirror: v2.33.0-develop
...
[2025-09-13 09:53:20.928] [LOG] Starting server on port 8080 ...
[2025-09-13 09:53:20.931] [WARN] You're using a full whitelist configuration to allow for all IPs
[2025-09-13 09:53:20.970] [ERROR]
────────────────────────────────────────────────────────────────
PORT IN USE: 0.0.0.0:8080
Another process (most likely another MagicMirror instance)
is already using this port.
Stop the other process (free the port) or use a different port.
────────────────────────────────────────────────────────────────
[2025-09-13 09:53:22.471] [INFO]
#### System Information ####
...
```
socket.io times out and closes the client side socket without any
callback
sendSocntNotification() from the server side data is lost as the socket
is closed. but the client doesn't know
increase the timeout
fixes#3380
Fixes#3253
Adds a configuration option to overwrite the default `User-Agent` header
that is send at least by the calendar and news module. Allows other
modules to use the individual user agent as well.
The configuration accepts either a string or a function:
```
var config =
{
...
userAgent: 'Mozilla/5.0 (My User Agent)',
...
}
```
or
```
var config =
{
...
userAgent: () => 'Mozilla/5.0 (My User Agent)',
...
}
```
---------
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <gitkraken@veeck.de>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Additionally to #3839 did some rework on the system logging.
- feat: include MagicMirror version (like Sam suggested in #3839)
- refactor: use more variables to get the string array less complex
- refactor: get `installedNodeVersion` from si.versions (with that it
was possible to drop the import of `execSync`)
- fix: `used node` was always the same as the installed one. Since
Electron comes with its own node version, this can differ. This is now
shown correctly (again?) with the use of `process.version`.
- a bit formatting
I think these changes make the code easier to understand and therefore
easier to maintain. Except for showing the MM version there is no big
difference for the user.
## before
```bash
##### System Information #####
- SYSTEM: manufacturer: Notebook; model: N650DU; virtual: false; timeZone: Europe/Berlin
- OS: platform: linux; distro: Debian GNU/Linux; release: 12; arch: x64; kernel: 5.10.0-20-amd64
- VERSIONS: electron: 36.3.2; used node: 22.15.0; installed node: 22.15.0; npm: 10.9.0; pm2: 6.0.6
- ENV: XDG_SESSION_TYPE: wayland; MM_CONFIG_FILE: config/config_MMM-PublicTransportHafas.js;
WAYLAND_DISPLAY: wayland-0; DISPLAY: :0; ELECTRON_ENABLE_GPU: undefined
- RAM: total: 15925.45 MB; free: 2716.90 MB; used: 13209.04 MB
- UPTIME: 259 minutes
```
## after
```bash
#### System Information ####
- SYSTEM: manufacturer: Notebook; model: N650DU; virtual: false; MM: 2.33.0-develop
- OS: platform: linux; distro: Debian GNU/Linux; release: 12; arch: x64; kernel: 5.10.0-20-amd64
- VERSIONS: electron: 36.3.2; used node: 22.15.1; installed node: 22.15.0; npm: 10.9.0; pm2: 6.0.6
- ENV: XDG_SESSION_TYPE: wayland; MM_CONFIG_FILE: config/config_MMM-PublicTransportHafas.js
WAYLAND_DISPLAY: wayland-0; DISPLAY: :0; ELECTRON_ENABLE_GPU: undefined
- RAM: total: 15925.45 MB; free: 2814.49 MB; used: 13110.96 MB
- OTHERS: uptime: 260 minutes; timeZone: Europe/Berlin
```
When we introduced the system information, I selected `###` as the
prefix for each line. While this doesn't cause any problems in the
terminal, when someone copies the output to an issue or the forum, every
line is formatted as a heading, which is not ideal. That's why I made
some rework and suggest these changes.
In addition to the formatting changes, I added some env and RAM details
plus the uptime. These are just suggestions – if you don't think they're
worth adding, I'm happy to remove them. We wanted to keep this block
compact.
@sdetweil, since you are often on the front line with the error messages
from users: Is there any information missing in the system block that
you often have to request additionally?
Feel free to request changes!
-----
## in the terminal
### before
```
[2025-07-09 21:58:36.943] [INFO] System information:
### SYSTEM: manufacturer: Notebook; model: N650DU; virtual: false
### OS: platform: linux; distro: Debian GNU/Linux; release: 12; arch: x64; kernel: 5.10.0-20-amd64
### VERSIONS: electron: 36.3.2; used node: 24.2.0; installed node: 24.2.0; npm: 10.9.0; pm2: 6.0.6
### OTHER: timeZone: Europe/Berlin; ELECTRON_ENABLE_GPU: undefined
```
-----
### after
```
[2025-07-09 21:57:47.604] [INFO]
##### System Information #####
- SYSTEM: manufacturer: Notebook; model: N650DU; virtual: false; timeZone: Europe/Berlin
- OS: platform: linux; distro: Debian GNU/Linux; release: 12; arch: x64; kernel: 5.10.0-20-amd64
- VERSIONS: electron: 36.3.2; used node: 24.2.0; installed node: 24.2.0; npm: 10.9.0; pm2: 6.0.6
- ENV: XDG_SESSION_TYPE: wayland; MM_CONFIG_FILE: undefined;
WAYLAND_DISPLAY: wayland-0; DISPLAY: :0; ELECTRON_ENABLE_GPU: undefined
- RAM: total: 15925.45 MB; free: 967.75 MB; used: 14957.70 MB
- UPTIME: 172 minutes
```
-----
## as markdown (in an issue or the forum)
### before
[2025-07-09 21:58:36.943] [INFO] System information:
### SYSTEM: manufacturer: Notebook; model: N650DU; virtual: false
### OS: platform: linux; distro: Debian GNU/Linux; release: 12; arch:
x64; kernel: 5.10.0-20-amd64
### VERSIONS: electron: 36.3.2; used node: 24.2.0; installed node:
24.2.0; npm: 10.9.0; pm2: 6.0.6
### OTHER: timeZone: Europe/Berlin; ELECTRON_ENABLE_GPU: undefined
-----
### after
[2025-07-09 21:57:47.604] [INFO]
##### System Information #####
- SYSTEM: manufacturer: Notebook; model: N650DU; virtual: false;
timeZone: Europe/Berlin
- OS: platform: linux; distro: Debian GNU/Linux; release: 12; arch: x64;
kernel: 5.10.0-20-amd64
- VERSIONS: electron: 36.3.2; used node: 24.2.0; installed node: 24.2.0;
npm: 10.9.0; pm2: 6.0.6
- ENV: XDG_SESSION_TYPE: wayland; MM_CONFIG_FILE: undefined;
WAYLAND_DISPLAY: wayland-0; DISPLAY: :0; ELECTRON_ENABLE_GPU: undefined
- RAM: total: 15925.45 MB; free: 967.75 MB; used: 14957.70 MB
- UPTIME: 172 minutes
In PR #3806 I noticed that ESLint did not complain about the use of
`console`. Then I realised that the rule `no-console` was not activated.
I have now changed this and replaced a few places where `console` was
used.
We can't apply the rule to all .js files because not all of them use our
logger. Therefore I had to add an extra config block for it.
I was always unhappy when maintaining dependency updates to have 3
`package.json` files.
This PR moves all deps into the main `package.json` and removes the
folders `fonts` and `vendor`.
If accepted I will update the docs too.
---------
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
`fs.F_OK` and `fs.R_OK` are [deprecated since a while node
20.8.0](https://nodejs.org/api/deprecations.html#DEP0176).
Node 24 now complains about them when running server mode (`node --run
server`):
```bash
[2025-05-23 23:11:44.932] [ERROR] (node:37733) [DEP0176] DeprecationWarning: fs.F_OK is deprecated, use fs.constants.F_OK instead
(Use `node --trace-deprecation ...` to show where the warning was created)
```
The replacements have been in place for a while, and this change should
work without any issues.
My proposal for #3761
* I use `flex` box for create region container
* I have moved `container` definition to `main.css` (for css tunning,
maybe it can be useful)
* I create `order` in module config for define module order display from
position
# Advantage:
We don't have to move module config in another place in array of modules
# Another advantage that i did'nt think:
We can change dynamicaly module order of a container:
- So, in this case, for a module config builder, (I won't mention the
name because otherwise I'll get angry...)
It can be usefull for a config preview (before saving config)
--> just change style css `order` module value for see preview
- Or, change `order` value in dev console for testing
# Disadvantages
I don't see any ;)
This has the advantage that the package manager is no longer involved
after the installation process.
However, previous start commands such as `npm run start` continue to
work. So we don't even have to adapt the documentation.
While debugging a 3rd party module, I looked at how modules are loaded
and realized that the `loadModules` method can be implemented much
simpler. This refactor makes the method easier to understand and
maintain.