head
head copied to clipboard
Fix setAttrs runs before head is ready
:link: Linked issue
resolve #75
:question: Type of change
- [ ] :book: Documentation (updates to the documentation or readme)
- [x] :lady_beetle: Bug fix (a non-breaking change that fixes an issue)
- [ ] :ok_hand: Enhancement (improving an existing functionality like performance)
- [ ] :sparkles: New feature (a non-breaking change that adds functionality)
- [ ] :warning: Breaking change (fix or feature that would cause existing functionality to change)
:books: Description
Nuxt3 runs the updateDOM
function directly before the head has htmlAttrs, and this is causing to clear existing attributes in the head; this happened during hydration
Please revert the format changes. Thanks.
Please revert the format changes. Thanks.
Done :+1:
Could you add some tests to it?
I tested this by patching it in my project (using yarn patch
), and it didn't fix the issue. See attached video (the background is initially green to emphasize the flash).
main.scss
html {
background-color: #0f0;
color: var(--text);
}
Then, in the Nuxt code:
useHead({
meta: 'theme' in reelOrEmbed ? generateOgMeta(reelOrEmbed) : [],
style: [
{
type: 'text/css',
children: `
:root {
--background: ${theme.background};
--background-contrast: ${bgContrastColor.value.toHex8String()};
--faded-overlay: ${fadedOverlay};
--text: ${theme.text};
${theme.link ? '--link: ' + theme.link + ';' : ''}
--primary: ${theme.primary};
--primary-faded: ${primaryFadedColor.toHex8String()};
}
`,
},
],
});
https://user-images.githubusercontent.com/12532733/187232695-14d97813-ec03-4e45-b320-f517e87b36a5.mp4
Hey @christian4leaflabs, If you're still interested in solving this one could you address the above comment and maybe add some tests in the nuxt3 e2e
Will close for now as it seems stale but please re-open if / when changes are made :)
This isn't stale, it's still an issue. And there's no currently proven fix that I'm aware of.
The issue isn't stale (https://github.com/vueuse/head/issues/75), the PR is though as it hasn't been updated since July without any progress towards merging it.
This PR doesn't solve the issue, anyway (I tried it). The only thing that worked for me was my debouncer to limit how many times the update method can be called, and this prevents the flicker.
Thanks for the details @ffxsam, would you mind sharing this code snippet in the issue https://github.com/vueuse/head/issues/75, it will be helpful when I attempt to fix it.
@harlan-zw Of course! I can't guarantee it's the most elegant. 😅 I was in a hurry and needed a fix, but maybe you can improve upon it.
Keep in mind, this is a yarn patch, so it's on the bundled index.mjs
file, not the original source code. Also, this patch includes the fix for the &
issue.
Diff file
diff --git a/dist/index.mjs b/dist/index.mjs
index 481b7343c20357bc198ebec977c5daaff0c25e24..ecfcaf61faece3b0a3a91fd14e60d7f20c947f10 100644
--- a/dist/index.mjs
+++ b/dist/index.mjs
@@ -57,8 +57,18 @@ var createElement = (tag, attrs, document) => {
return el;
};
+var debounce = (fn, delay = 0) => {
+ let timer;
+ return (...args) => {
+ clearTimeout(timer);
+ timer = setTimeout(() => {
+ fn(...args);
+ }, delay);
+ };
+};
+
// src/stringify-attrs.ts
-var htmlEscape = (str) => str.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
+var htmlEscape = (str) => str.replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
var stringifyAttrs = (attributes) => {
const handledAttributes = [];
for (let [key, value] of Object.entries(attributes)) {
@@ -300,7 +310,7 @@ var createHead = (initHeadObject) => {
removeHeadObjs(objs) {
allHeadObjs = allHeadObjs.filter((_objs) => _objs !== objs);
},
- updateDOM(document = window.document) {
+ updateDOM: debounce((document = window.document) => {
let title;
let htmlAttrs = {};
let bodyAttrs = {};
@@ -332,8 +342,8 @@ var createHead = (initHeadObject) => {
}
previousTags.clear();
Object.keys(actualTags).forEach((i) => previousTags.add(i));
- }
- };
+ }, 500),
+ }
return head;
};
var IS_BROWSER = typeof window !== "undefined";
</details>