1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Dedupe only items with unique key (#5800)

Fixes #3705
Fixes #4656

- No longer automatically dedupe certain tags. Only the ones we know are *never* going to be duplicate like charSet, title etc.
- Fix `key=""` behavior, making sure that if a unique key is provided tags are deduped based on that.

For example:

```jsx
<meta property='fb:pages' content='one'>
<meta property='fb:pages' content='two'>
```

Would currently cause

```jsx
<meta property='fb:pages' content='two'>
```

### After this change:

```jsx
<meta property='fb:pages' content='one'>
<meta property='fb:pages' content='two'>
```

Then if you use next/head multiple times / want to be able to override:

```jsx
<meta property='fb:pages' content='one' key="not-unique-key">
<meta property='fb:pages' content='two' key="not-unique-key">
```

Would cause:

```jsx
<meta property='fb:pages' content='two'>
```

As `key` gets deduped correctly after this PR, similar to how React itself works.
This commit is contained in:
Tim Neutkens 2018-12-03 17:28:42 +01:00 committed by GitHub
parent 58f5dd297a
commit 9890e06907
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 8 deletions

View file

@ -52,8 +52,7 @@ function onStateChange (head) {
}
}
const METATYPES = ['name', 'httpEquiv', 'charSet', 'itemProp', 'property']
const ALLOWED_DUPLICATES = ['article:tag', 'og:image', 'og:image:alt', 'og:image:width', 'og:image:height', 'og:image:type', 'og:image:secure_url', 'og:image:url']
const METATYPES = ['name', 'httpEquiv', 'charSet', 'itemProp']
/*
returns a function for filtering head child elements
@ -71,6 +70,7 @@ function unique () {
if (h.key && h.key.indexOf('.$') === 0) {
if (keys.has(h.key)) return false
keys.add(h.key)
return true
}
switch (h.type) {
case 'title':
@ -89,7 +89,7 @@ function unique () {
} else {
const category = h.props[metatype]
const categories = metaCategories[metatype] || new Set()
if (categories.has(category) && ALLOWED_DUPLICATES.indexOf(category) === -1) return false
if (categories.has(category)) return false
categories.add(category)
metaCategories[metatype] = categories
}

View file

@ -13,8 +13,8 @@ export default () => <div>
{/* allow duplicates for specific tags */}
<meta property='article:tag' content='tag1' key='tag1key' />
<meta property='article:tag' content='tag2' key='tag2key' />
<meta property='dedupe:tag' content='tag3' key='tag3key' />
<meta property='dedupe:tag' content='tag4' key='tag4key' />
<meta property='dedupe:tag' content='tag3' key='same-key' />
<meta property='dedupe:tag' content='tag4' key='same-key' />
<meta property='og:image' content='ogImageTag1' key='ogImageTag1Key' />
<meta property='og:image' content='ogImageTag2' key='ogImageTag2Key' />
<meta property='og:image:alt' content='ogImageAltTag1' key='ogImageAltTag1Key' />
@ -30,6 +30,9 @@ export default () => <div>
<meta property='og:image:url' content='ogImageUrlTag1' key='ogImageUrlTag1Key' />
<meta property='og:image:url' content='ogImageUrlTag2' key='ogImageUrlTag2Key' />
<meta property='fb:pages' content='fbpages1' />
<meta property='fb:pages' content='fbpages2' />
<React.Fragment>
<title>Fragment title</title>
<meta content='meta fragment' />
@ -43,5 +46,5 @@ export default () => <div>
<link rel='stylesheet' href='dedupe-style.css' key='my-style' />
<link rel='stylesheet' href='dedupe-style.css' key='my-style' />
</Head>
<h1>I can haz meta tags</h1>
<h1>I can have meta tags</h1>
</div>

View file

@ -33,7 +33,7 @@ export default function ({ app }, suiteName, render, fetch) {
const html = await (render('/head'))
expect(html.includes('<meta charSet="iso-8859-5" class="next-head"/>')).toBeTruthy()
expect(html.includes('<meta content="my meta" class="next-head"/>')).toBeTruthy()
expect(html.includes('I can haz meta tags')).toBeTruthy()
expect(html.includes('I can have meta tags')).toBeTruthy()
})
test('header helper dedupes tags', async () => {
@ -65,7 +65,8 @@ export default function ({ app }, suiteName, render, fetch) {
expect(html).toContain('<meta property="og:image:secure_url" content="ogImageSecureUrlTag1" class="next-head"/>')
expect(html).toContain('<meta property="og:image:secure_url" content="ogImageSecureUrlTag2" class="next-head"/>')
expect(html).toContain('<meta property="og:image:url" content="ogImageUrlTag1" class="next-head"/>')
expect(html).toContain('<meta property="og:image:url" content="ogImageUrlTag2" class="next-head"/>')
expect(html).toContain('<meta property="fb:pages" content="fbpages1" class="next-head"/>')
expect(html).toContain('<meta property="fb:pages" content="fbpages2" class="next-head"/>')
})
test('header helper renders Fragment children', async () => {