vueuse/head

ampersands get escaped in URLS

acidjazz opened this issue · 7 comments

  renderHeadToString({
    headTags: [
      {
        tag: 'script',
        props: {
          async: true,
          hid: 'maps-googleapis',
          src: 'https://maps.googleapis.com/maps/api/js?key=example&libraries=places',
        },
      },
    ],
  }).headTags

results in:

<script async hid="maps-googleapis" src="https://maps.googleapis.com/maps/api/js?key=example&amp;libraries=places"></script><meta name="head:count" content="1">

https://github.com/vueuse/head/blob/main/src/stringify-attrs.ts#L2-L32

https://github.com/vueuse/head/blob/main/src/index.ts#L347-L362

Here's a reproduction.

Anyone found a workaround for this?

@stafyniaksacha This is my local patch (using yarn's patch/patch-commit feature). You should be using the latest yarn to do this (yarn 3.2.3).

Add this to your package.json:

  "resolutions": {
    "@vueuse/head@^0.7.9": "patch:@vueuse/head@npm%3A0.7.9#./.yarn/patches/@vueuse-head-npm-0.7.9-ad2f8578c9.patch"
  },

Then create this file:

.yarn/patches/@vueuse-head-npm-0.7.9-ad2f8578c9.patch

diff --git a/dist/index.js b/dist/index.js
index bf5e5100a01ae054ccea4da4a12b0784fe0b5840..0722bb95bbce708354d8f3ea8b42ade4966b7ad2 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -74,7 +74,7 @@ var createElement = (tag, attrs, document) => {
 };
 
 // src/stringify-attrs.ts
-var htmlEscape = (str) => str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
+var htmlEscape = (str) => str.replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
 var stringifyAttrs = (attributes) => {
   const handledAttributes = [];
   for (let [key, value] of Object.entries(attributes)) {
diff --git a/dist/index.mjs b/dist/index.mjs
index 481b7343c20357bc198ebec977c5daaff0c25e24..ab8fbbf57c0c12d7482e498a468a11a4b564a869 100644
--- a/dist/index.mjs
+++ b/dist/index.mjs
@@ -58,7 +58,7 @@ var createElement = (tag, attrs, document) => {
 };
 
 // src/stringify-attrs.ts
-var htmlEscape = (str) => str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
+var htmlEscape = (str) => str.replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
 var stringifyAttrs = (attributes) => {
   const handledAttributes = [];
   for (let [key, value] of Object.entries(attributes)) {

Run yarn, and you should be good to go!

Does the escaping actually cause issues with loading the URL though?

My understanding and testing it seems like it works fine escaped

Yes, it does cause problems for sure. It's not escaping anything, it's replacing & with &amp; which is not valid in a URL.

Does the escaping actually cause issues with loading the URL though?

My understanding and testing it seems like it works fine escaped

It breaks any functionality of needing to pass parameters to JS libraries, which is how all of googles API's work

Thanks for confirming, will look into it soon

Should be fixed in https://github.com/vueuse/head/releases/tag/v0.7.13

Let me know if you have any issues with it