Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow manually setting amphtml #9098

Merged
merged 10 commits into from
Oct 18, 2019
Merged
86 changes: 45 additions & 41 deletions packages/next/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,49 +273,53 @@ export class Head extends Component<
let hasCanonicalRel = false

// show warning and remove conflicting amp head tags
head = !inAmpMode
? head
: React.Children.map(head || [], child => {
if (!child) return child
const { type, props } = child
let badProp: string = ''

if (type === 'meta' && props.name === 'viewport') {
badProp = 'name="viewport"'
} else if (type === 'link' && props.rel === 'canonical') {
hasCanonicalRel = true
} else if (type === 'link' && props.rel === 'amphtml') {
hasAmphtmlRel = true
} else if (type === 'script') {
// only block if
// 1. it has a src and isn't pointing to ampproject's CDN
// 2. it is using dangerouslySetInnerHTML without a type or
// a type of text/javascript
if (
(props.src && props.src.indexOf('ampproject') < -1) ||
(props.dangerouslySetInnerHTML &&
(!props.type || props.type === 'text/javascript'))
) {
badProp = '<script'
Object.keys(props).forEach(prop => {
badProp += ` ${prop}="${props[prop]}"`
})
badProp += '/>'
}
head = React.Children.map(head || [], child => {
if (!child) return child
const { type, props } = child

if (inAmpMode) {
let badProp: string = ''

if (type === 'meta' && props.name === 'viewport') {
badProp = 'name="viewport"'
} else if (type === 'link' && props.rel === 'canonical') {
hasCanonicalRel = true
} else if (type === 'script') {
// only block if
// 1. it has a src and isn't pointing to ampproject's CDN
// 2. it is using dangerouslySetInnerHTML without a type or
// a type of text/javascript
if (
(props.src && props.src.indexOf('ampproject') < -1) ||
(props.dangerouslySetInnerHTML &&
(!props.type || props.type === 'text/javascript'))
) {
badProp = '<script'
Object.keys(props).forEach(prop => {
badProp += ` ${prop}="${props[prop]}"`
})
badProp += '/>'
}
}

if (badProp) {
console.warn(
`Found conflicting amp tag "${
child.type
}" with conflicting prop ${badProp} in ${
__NEXT_DATA__.page
}. https://err.sh/next.js/conflicting-amp-tag`
)
return null
}
return child
})
if (badProp) {
console.warn(
`Found conflicting amp tag "${
child.type
}" with conflicting prop ${badProp} in ${
__NEXT_DATA__.page
}. https://err.sh/next.js/conflicting-amp-tag`
)
return null
}
} else {
// non-amp mode
if (type === 'link' && props.rel === 'amphtml') {
hasAmphtmlRel = true
}
}
return child
})

// try to parse styles from fragment for backwards compat
const curStyles: React.ReactElement[] = Array.isArray(styles)
Expand Down
1 change: 1 addition & 0 deletions test/integration/amphtml/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ describe('AMP Usage', () => {
const html = await renderViaHTTP(appPort, '/manual-rels')
const $ = cheerio.load(html)
expect($('link[rel=amphtml]').attr('href')).toBe('/my-custom-amphtml')
expect($('link[rel=amphtml]')).toHaveLength(1)
})
})

Expand Down