diff --git a/libs/utils/utils.js b/libs/utils/utils.js
index 6ada41f80c..447ea78e0e 100644
--- a/libs/utils/utils.js
+++ b/libs/utils/utils.js
@@ -901,7 +901,7 @@ async function loadPostLCP(config) {
export function scrollToHashedElement(hash) {
if (!hash) return;
- const elementId = hash.slice(1);
+ const elementId = decodeURIComponent(hash).slice(1);
let targetElement;
try {
targetElement = document.querySelector(`#${elementId}:not(.dialog-modal)`);
diff --git a/test/utils/mocks/body.html b/test/utils/mocks/body.html
index fbe8805095..d3ed6d2e65 100644
--- a/test/utils/mocks/body.html
+++ b/test/utils/mocks/body.html
@@ -2,6 +2,7 @@
+


diff --git a/test/utils/utils.test.js b/test/utils/utils.test.js
index fdd016ed19..e0eac39bec 100644
--- a/test/utils/utils.test.js
+++ b/test/utils/utils.test.js
@@ -473,6 +473,17 @@ describe('Utils', () => {
utils.scrollToHashedElement('');
expect(scrollToCalled).to.be.false;
});
+
+ it('should scroll to the hashed element with special character', () => {
+ let scrollToCalled = false;
+ window.scrollTo = () => {
+ scrollToCalled = true;
+ };
+
+ utils.scrollToHashedElement('#tools-f%C3%BCr-das-verhalten');
+ expect(scrollToCalled).to.be.true;
+ expect(document.getElementById('tools-für-das-verhalten')).to.exist;
+ });
});
describe('useDotHtml', async () => {