diff --git a/src/Helmet.js b/src/Helmet.js
index d88ee7e4..5278a8af 100644
--- a/src/Helmet.js
+++ b/src/Helmet.js
@@ -14,22 +14,22 @@ import {TAG_NAMES, VALID_TAG_NAMES} from "./HelmetConstants.js";
const Helmet = Component =>
class HelmetWrapper extends React.Component {
/**
- * @param {Object} base: {"target": "_blank", "href": "http://mysite.com/"}
- * @param {Object} bodyAttributes: {"className": "root"}
- * @param {String} defaultTitle: "Default Title"
- * @param {Boolean} defer: true
- * @param {Boolean} encodeSpecialCharacters: true
- * @param {Object} htmlAttributes: {"lang": "en", "amp": undefined}
- * @param {Array} link: [{"rel": "canonical", "href": "http://mysite.com/example"}]
- * @param {Array} meta: [{"name": "description", "content": "Test description"}]
- * @param {Array} noscript: [{"innerHTML": " console.log(newState)"
- * @param {Array} script: [{"type": "text/javascript", "src": "http://mysite.com/js/test.js"}]
- * @param {Array} style: [{"type": "text/css", "cssText": "div { display: block; color: blue; }"}]
- * @param {String} title: "Title"
- * @param {Object} titleAttributes: {"itemprop": "name"}
- * @param {String} titleTemplate: "MySite.com - %s"
- */
+ * @param {Object} base: {"target": "_blank", "href": "http://mysite.com/"}
+ * @param {Object} bodyAttributes: {"className": "root"}
+ * @param {String} defaultTitle: "Default Title"
+ * @param {Boolean} defer: true
+ * @param {Boolean} encodeSpecialCharacters: true
+ * @param {Object} htmlAttributes: {"lang": "en", "amp": undefined}
+ * @param {Array} link: [{"rel": "canonical", "href": "http://mysite.com/example"}]
+ * @param {Array} meta: [{"name": "description", "content": "Test description"}]
+ * @param {Array} noscript: [{"innerHTML": " console.log(newState)"
+ * @param {Array} script: [{"type": "text/javascript", "src": "http://mysite.com/js/test.js"}]
+ * @param {Array} style: [{"type": "text/css", "cssText": "div { display: block; color: blue; }"}]
+ * @param {String} title: "Title"
+ * @param {Object} titleAttributes: {"itemprop": "name"}
+ * @param {String} titleTemplate: "MySite.com - %s"
+ */
static propTypes = {
base: PropTypes.object,
bodyAttributes: PropTypes.object,
diff --git a/src/HelmetUtils.js b/src/HelmetUtils.js
index 63ad85a6..9bc3284d 100644
--- a/src/HelmetUtils.js
+++ b/src/HelmetUtils.js
@@ -416,40 +416,61 @@ const updateAttributes = (tagName, attributes) => {
}
};
+const setAttributes = (node, tag) => {
+ for (const attribute in tag) {
+ if (tag.hasOwnProperty(attribute)) {
+ if (attribute === TAG_PROPERTIES.INNER_HTML) {
+ node.innerHTML = tag.innerHTML;
+ } else if (attribute === TAG_PROPERTIES.CSS_TEXT) {
+ if (node.styleSheet) {
+ node.styleSheet.cssText = tag.cssText;
+ } else {
+ node.appendChild(document.createTextNode(tag.cssText));
+ }
+ } else {
+ const value = typeof tag[attribute] === "undefined"
+ ? ""
+ : tag[attribute];
+ node.setAttribute(attribute, value);
+ }
+ }
+ }
+};
+
const updateTags = (type, tags) => {
const headElement = document.head || document.querySelector(TAG_NAMES.HEAD);
const tagNodes = headElement.querySelectorAll(
`${type}[${HELMET_ATTRIBUTE}]`
);
- const oldTags = Array.prototype.slice.call(tagNodes);
+ const oldTags = Array.prototype.slice.call(tagNodes) || [];
const newTags = [];
+ const updatedTags = [];
let indexToDelete;
-
if (tags && tags.length) {
tags.forEach(tag => {
- const newElement = document.createElement(type);
+ // Check if exists?
+ let found;
+ if (oldTags && Array.isArray(oldTags)) {
+ found = oldTags.find(node => {
+ const name =
+ node.getAttribute("name") ||
+ node.getAttribute("property");
+ return name === (tag.name || tag.property);
+ });
+ }
- for (const attribute in tag) {
- if (tag.hasOwnProperty(attribute)) {
- if (attribute === TAG_PROPERTIES.INNER_HTML) {
- newElement.innerHTML = tag.innerHTML;
- } else if (attribute === TAG_PROPERTIES.CSS_TEXT) {
- if (newElement.styleSheet) {
- newElement.styleSheet.cssText = tag.cssText;
- } else {
- newElement.appendChild(
- document.createTextNode(tag.cssText)
- );
- }
- } else {
- const value = typeof tag[attribute] === "undefined"
- ? ""
- : tag[attribute];
- newElement.setAttribute(attribute, value);
- }
+ if (found) {
+ const index = oldTags.indexOf(found);
+ if (index > -1) {
+ oldTags.splice(index, 1);
}
+ setAttributes(found, tag);
+ updatedTags.push(found);
+ return;
}
+ const newElement = document.createElement(type);
+ setAttributes(newElement, tag);
newElement.setAttribute(HELMET_ATTRIBUTE, "true");
// Remove a duplicate tag from domTagstoRemove, so it isn't cleared.
@@ -471,7 +492,7 @@ const updateTags = (type, tags) => {
return {
oldTags,
- newTags
+ newTags: [...updatedTags, ...newTags]
};
};
diff --git a/test/HelmetDeclarativeTest.js b/test/HelmetDeclarativeTest.js
index bdcf5229..28776e3f 100644
--- a/test/HelmetDeclarativeTest.js
+++ b/test/HelmetDeclarativeTest.js
@@ -3485,7 +3485,6 @@ describe("Helmet - Declarative API", () => {
expect(spy.called).to.equal(true);
addedTags = spy.getCall(0).args[1];
removedTags = spy.getCall(0).args[2];
-
expect(addedTags).to.have.property("metaTags");
expect(addedTags.metaTags).to.have.deep.property("[0]");
expect(addedTags.metaTags[0].outerHTML).to.equal(
diff --git a/test/HelmetTest.js b/test/HelmetTest.js
index c472e2c8..91edf2ff 100644
--- a/test/HelmetTest.js
+++ b/test/HelmetTest.js
@@ -3183,7 +3183,6 @@ describe("Helmet", () => {
expect(spy.called).to.equal(true);
addedTags = spy.getCall(0).args[1];
removedTags = spy.getCall(0).args[2];
-
expect(addedTags).to.have.property("metaTags");
expect(addedTags.metaTags).to.have.deep.property("[0]");
expect(addedTags.metaTags[0].outerHTML).to.equal(