diff --git a/packages/next/client/head-manager.js b/packages/next/client/head-manager.js
index 865f50bc52a88..5eec36503c0ce 100644
--- a/packages/next/client/head-manager.js
+++ b/packages/next/client/head-manager.js
@@ -95,6 +95,9 @@ function reactElementToDOM({ type, props }) {
if (!props.hasOwnProperty(p)) continue
if (p === 'children' || p === 'dangerouslySetInnerHTML') continue
+ // we don't render undefined props to the DOM
+ if (props[p] === undefined) continue
+
const attr = DOMAttributeNames[p] || p.toLowerCase()
el.setAttribute(attr, props[p])
}
diff --git a/test/integration/client-navigation/pages/head.js b/test/integration/client-navigation/pages/head.js
index 6b868ec0de995..ae698dc67e70e 100644
--- a/test/integration/client-navigation/pages/head.js
+++ b/test/integration/client-navigation/pages/head.js
@@ -16,6 +16,9 @@ export default () => (
+ {/* this will not render the content prop */}
+
+
{/* allow duplicates for specific tags */}
diff --git a/test/integration/client-navigation/test/index.test.js b/test/integration/client-navigation/test/index.test.js
index c236e8bd249ac..81aab25d0b341 100644
--- a/test/integration/client-navigation/test/index.test.js
+++ b/test/integration/client-navigation/test/index.test.js
@@ -1097,6 +1097,15 @@ describe('Client Navigation', () => {
await browser.close()
})
+ it('should handle undefined prop in head client-side', async () => {
+ const browser = await webdriver(context.appPort, '/head')
+ const value = await browser.eval(
+ `document.querySelector('meta[name="empty-content"]').hasAttribute('content')`
+ )
+
+ expect(value).toBe(false)
+ })
+
renderingSuite(
(p, q) => renderViaHTTP(context.appPort, p, q),
(p, q) => fetchViaHTTP(context.appPort, p, q)
diff --git a/test/integration/client-navigation/test/rendering.js b/test/integration/client-navigation/test/rendering.js
index b7679fbb45796..4bc7ef238d89d 100644
--- a/test/integration/client-navigation/test/rendering.js
+++ b/test/integration/client-navigation/test/rendering.js
@@ -17,6 +17,14 @@ export default function(render, fetch) {
expect(html.includes('My component!')).toBeTruthy()
})
+ it('should handle undefined prop in head server-side', async () => {
+ const html = await render('/head')
+ const $ = cheerio.load(html)
+ const value = 'content' in $('meta[name="empty-content"]').attr()
+
+ expect(value).toBe(false)
+ })
+
test('renders with fragment syntax', async () => {
const html = await render('/fragment-syntax')
expect(html.includes('My component!')).toBeTruthy()