diff --git a/src/HelmetUtils.js b/src/HelmetUtils.js index 54cad57e..be3ff0c9 100644 --- a/src/HelmetUtils.js +++ b/src/HelmetUtils.js @@ -300,9 +300,13 @@ const handleClientStateChange = (newState) => { }); }; +const flattenArray = (possibleArray) => { + return Array.isArray(possibleArray) ? possibleArray.join("") : possibleArray; +}; + const updateTitle = (title, attributes) => { if (typeof title !== "undefined" && document.title !== title) { - document.title = Array.isArray(title) ? title.join("") : title; + document.title = flattenArray(title); } updateAttributes(TAG_NAMES.TITLE, attributes); @@ -410,9 +414,10 @@ const generateElementAttributesAsString = (attributes) => Object.keys(attributes const generateTitleAsString = (type, title, attributes, encode) => { const attributeString = generateElementAttributesAsString(attributes); + const flattenedTitle = flattenArray(title); return attributeString - ? `<${type} ${HELMET_ATTRIBUTE}="true" ${attributeString}>${encodeSpecialCharacters(title, encode)}` - : `<${type} ${HELMET_ATTRIBUTE}="true">${encodeSpecialCharacters(title, encode)}`; + ? `<${type} ${HELMET_ATTRIBUTE}="true" ${attributeString}>${encodeSpecialCharacters(flattenedTitle, encode)}` + : `<${type} ${HELMET_ATTRIBUTE}="true">${encodeSpecialCharacters(flattenedTitle, encode)}`; }; const generateTagsAsString = (type, tags, encode) => tags.reduce((str, tag) => { diff --git a/test/HelmetDeclarativeTest.js b/test/HelmetDeclarativeTest.js index 331c704e..1607a41c 100644 --- a/test/HelmetDeclarativeTest.js +++ b/test/HelmetDeclarativeTest.js @@ -2167,6 +2167,7 @@ describe("Helmet - Declarative API", () => { const stringifiedTitle = `Dangerous <script> include`; const unEncodedStringifiedTitle = `This is text and & and '.`; const stringifiedTitleWithItemprop = `Title with Itemprop`; + const stringifiedTitleWithTitleExpression = `Title: Some Great Title`; const stringifiedBaseTag = ``; const stringifiedMetaTags = [ @@ -2568,6 +2569,30 @@ describe("Helmet - Declarative API", () => { .that.equals(stringifiedTitle); }); + it("renders title and allows children containing expressions", (done) => { + const someValue = "Some Great Title"; + + ReactDOM.render( + + Title: {someValue} + , + container + ); + + const head = Helmet.rewind(); + + expect(head.title).to.exist; + expect(head.title).to.respondTo("toString"); + + requestIdleCallback(() => { + expect(head.title.toString()) + .to.be.a("string") + .that.equals(stringifiedTitleWithTitleExpression); + + done(); + }); + }); + it("renders title with itemprop name as string", () => { ReactDOM.render(