next.js
next.js copied to clipboard
Duplicate "amp-custom" style tag on AMP pages
Verify canary release
- [X] I verified that the issue exists in Next.js canary release
Provide environment information
- Operating System:
- Platform: win32
- Arch: x64
- Version: Windows 10 Home
- Binaries:
- Node: 16.14.2
- npm: N/A
- Yarn: N/A
- pnpm: N/A
- Relevant packages:
- next: 12.1.4
- react: 18.0.0
- react-dom: 18.0.0
What browser are you using? (if relevant)
Microsoft Edge 100.0.1185.39
How are you deploying your application? (if relevant)
No response
Describe the Bug
The issue is that when I generate an AMP-only page, an empty <style amp-custom></style>
is added to the head
, causing the following error after I add my own styles using raw-loader
:
/amp/[...slug] error The tag 'style amp-custom' appears more than once in the document. https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#stylesheets
Expected Behavior
Next.js should add my styles to the already created style tag, or not create an empty tag when building.
To Reproduce
-
Create an AMP-only page
export const config = { amp: true };
-
Import the styles using
raw-loader
and add them to the headimport style from '!!raw-loader!@/styles/amp.css';
<style amp-custom="" dangerouslySetInnerHTML={{ __html: style }} />
-
Open the page in the browser
is there any update with this?
Any update ?
facing the same issue, any workaround for this ?
Same issue here, any update? The behaviour is strange, you end up with 2 style tags, one with rules removed and other attributes, but amp-custom attribute remains in place, causing amp validator to fail.
<style id="amp-css" type="text/css" amp-custom="">body{background:pink}</style>
<style amp-custom></style>
If you remove the amp-custom
prop from the style tag, you then have the empty tag with amp-custom present still, but an invalid first tag.
I used the Next.js custom document to populate the empty <style amp-custom>
contents.
import Document from 'next/document'
export default class MyDocument extends Document {
static async getInitialProps (ctx: DocumentContext):Promise<DocumentInitialProps> {
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
<style amp-custom="" dangerouslySetInnerHTML={{
__html: `amp-story { background: '#000'; }`
}} />
</>
)
}
}
}
For more info: https://github.com/vercel/next.js/blob/ceb07ff00c59e95b4473a945ecba566471ff0d94/packages/next/pages/_document.tsx#L825
@abhu-A-J , your 'more info' helped. Had same problem and looked into _document.tsx and it seems styles can be passed (though not 100% sure how...).
- NextJS only support CSS-in-JS(as of now). https://nextjs.org/docs/advanced-features/amp-support/introduction
- CSS-in-JS has a styled-jsx. Personally: I think this is the easiest for now, just slap style jsx into a node. https://nextjs.org/docs/basic-features/built-in-css-support
- There's more info on https://beta.nextjs.org/docs/styling/css-in-js. Which i got lost in what it explains and seems too complicated to configure; so for now sticking to styled-jsx.
A sample: please replace ' with (tilde)
const AmpPage = () => { return ( <> <amp-carousel>...</amp-carousel> <style jsx>{' .amp-carousel-slide { padding: 40px; } '}</style> </>) }