From fc4adcdf4df407462b3721b48ec2e336af7beca9 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Wed, 28 Oct 2026 13:44:10 +0100 Subject: [PATCH] :bug: Move the CSS @charset to the start of the bundled stylesheet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sass adds @charset "UTF-8" to every module with non-ASCII characters, and concatSass joined the modules as they came, so main.css carried it in the middle of the file. Browsers only honor @charset as the first rule, and the server sends text/css with no charset. When the browser did not take the page encoding for the stylesheet, it read main.css as Latin-1 and CSS content such as the bullet of the library element counts showed as "•". Drop every @charset while joining the modules and put one at the start. Closes #12677 AI-assisted-by: claude-opus-5-5 --- frontend/scripts/_helpers.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/frontend/scripts/_helpers.js b/frontend/scripts/_helpers.js index 60c59e8f6d..9a6bf14ec8 100644 --- a/frontend/scripts/_helpers.js +++ b/frontend/scripts/_helpers.js @@ -165,9 +165,22 @@ export async function compileSassAll(worker) { export function concatSass(data) { const output = []; + const charset = '@charset "UTF-8";'; + let hasCharset = false; + // Sass adds @charset to each file with non-ASCII characters. Browsers + // only honor it as the first rule of the stylesheet, so move it there. for (let path of data.items) { - output.push(data.index[path]); + let css = data.index[path]; + if (css.includes(charset)) { + hasCharset = true; + css = css.replaceAll(charset + "\n", "").replaceAll(charset, ""); + } + output.push(css); + } + + if (hasCharset) { + output.unshift(charset); } return output.join("\n");