next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Duplicate "amp-custom" style tag on AMP pages

Open scajal opened this issue 2 years ago • 3 comments

Verify canary release

  • [X] I verified that the issue exists in Next.js canary release

Provide environment information

  1. Operating System:
  • Platform: win32
  • Arch: x64
  • Version: Windows 10 Home
  1. Binaries:
  • Node: 16.14.2
  • npm: N/A
  • Yarn: N/A
  • pnpm: N/A
  1. 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

  1. Create an AMP-only page export const config = { amp: true };

  2. Import the styles using raw-loader and add them to the head import style from '!!raw-loader!@/styles/amp.css'; <style amp-custom="" dangerouslySetInnerHTML={{ __html: style }} />

  3. Open the page in the browser

scajal avatar Apr 12 '22 20:04 scajal

is there any update with this?

dincerdegre avatar May 27 '22 03:05 dincerdegre

Any update ?

Princenick-BL avatar Sep 09 '22 20:09 Princenick-BL

facing the same issue, any workaround for this ?

shivaprasadks avatar Sep 21 '22 12:09 shivaprasadks

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.

chriseagle avatar Sep 30 '22 15:09 chriseagle

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

abhushanaj avatar Oct 24 '22 05:10 abhushanaj

@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...).

  1. NextJS only support CSS-in-JS(as of now). https://nextjs.org/docs/advanced-features/amp-support/introduction
  2. 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
  3. 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> </>) }

yoonghan avatar Nov 28 '22 07:11 yoonghan