Next.JS + AMP CSS
Asked Answered
L

5

3

I'm having trouble with AMP and CSS in Next.js. In my head component I have:

<Head>
    <style amp-custom>{`
        // CSS Here
    `}</style>
</Head>

In the HTML source it shows up as <style amp-custom=""></style><style>(CSS Here)</style>

In the console I get this error: The mandatory attribute 'amp-custom' is missing in tag 'style amp-custom (transformed)'.

How can I work with AMPHTML's rules on CSS and Next both? Every other method I've tried (such as importing from a file using @zeit/next-sass) causes the CSS to not be rendered at all. This is the only working version I've found.

Loretaloretta answered 25/12, 2019 at 21:59 Comment(0)
L
4

...It has to be: <style jsx>...</style>. Very dumb mistake that I've been looking for workarounds on all day. :/

Loretaloretta answered 25/12, 2019 at 22:30 Comment(1)
I notice that adding 'global' tag to 'style jsx' element or not is the same. All style elements go to amp-custom style tag, because it can only be one per page. Official source: amp.dev/documentation/guides-and-tutorials/develop/…Annmarieannnora
E
6

Try this:

<Head>
    <style
      amp-custom=""
      dangerouslySetInnerHTML={{
        __html: `
          amp-img {
            border: 1px solid black;
          }
        `,
      }}
    ></style>
</Head>
Erikaerikson answered 18/11, 2020 at 9:13 Comment(2)
Thanks, finnaly after reafding for hours, thank you I was actually doing this and it was not working <style>{this.props.styleTags[0].props.dangerouslySetInnerHTML.__html}</style> or <style amp-custom="">{this.props.styleTags[0].props.dangerouslySetInnerHTML.__html}</style>Sarazen
Yours is the only working solution I foundSarazen
L
4

...It has to be: <style jsx>...</style>. Very dumb mistake that I've been looking for workarounds on all day. :/

Loretaloretta answered 25/12, 2019 at 22:30 Comment(1)
I notice that adding 'global' tag to 'style jsx' element or not is the same. All style elements go to amp-custom style tag, because it can only be one per page. Official source: amp.dev/documentation/guides-and-tutorials/develop/…Annmarieannnora
E
4

As of Sept 2020, I've been having this issue too. I'm new at this, but with no help from the official tutorials. I did find a workaround.

First, I want to point out a couple of things from Next.js that they tell you.

  1. non-AMP page styles are usually placed in _document.js from the next.js example.
</Head>
<style jsx global>{ reset }</style>
<style jsx global>{ globals }</style>
<body>
  <Main />
  <NextScript />
 </body>
  1. They mention in the tutorial to put <style amp-custom>. They don't say where, but it should be within the <Head></Head> of index.js (or whatever .js file for individual pages) OR _document.js for every page.

Ok, sounds good, BUT it's partially wrong!

I will explain what I found it does when turn on amp pages on in Next.JS.

So on an individual page, such as index.js, you need to this code at the top:

export const config = {
  amp: true,
}

Then you have to put this in the return function:

const isAmp = useAmp()

Standard instructions from the tutorial. Now AMP is turned on, here's what happens:

  1. Anything in <style amp-custom> is turned into a <style>

  2. anything that is in <style jsx> is turned into a <style amp-custom> tag.

  3. In addition to #2, it injects a unique random index that ruins any css code in that gets put into the generated <style amp-custom> tag.

 <style amp-custom>.jsx-2373233908{/* your CSS code that you put in <style jsx> from before */}</style>

and that .jsx-########### throws a "/ error CSS syntax error in tag 'style amp-custom' - incomplete declaration." when you try to compile.

Is this opposite and odd behavior. YES. I don't get why it does it, but I'm a newb.

So my workaround goes like this:

  1. Install your CSS framework package or put your CSS file into the styles folder (let's say located at : ./styles/styles.css)
  2. I also add raw loader from your terminal window. Because I like to put my css in a file, not type it inlined with the code. Let's be realistic, you're going to separate CSS and you'll need to load that file in.

npm install raw-loader --save-dev

  1. Load the CSS in your _document.js (here's my whole _document.js). I use "}" and "{" with fixCSS to escape the .jsx-########### and the injected code magically disappears.
import Document, { Html, Head, Main, NextScript } from 'next/document'

import styleCSS from '!!raw-loader!../styles/styles.css';
const fixCSS = `}${styleCSS}{`;

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html lang="en">
      <Head>
      </Head>
      <style jsx>{`
      ${fixCSS}
    ` }</style>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}
export default MyDocument

That's it. Now your imported CSS is shown on AMP pages. Remember this is for sept 2020 using these packages in my package.json:

  "dependencies": {
    "amp": "^0.3.1",
    "next": "^9.5.3-canary.25",
    "next-env": "^1.1.1",
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
},
  "devDependencies": {
    "cssnano": "^4.1.10",
    "now": "^19.2.0",
    "raw-loader": "^4.0.1"
  },
Earthlight answered 3/9, 2020 at 23:19 Comment(1)
Thank you, this worked for my use case of having a specific amp file in the /pages dirPastime
C
0

Try:

<style jsx amp-custom>
`
  ... my css
`
</style>

I just tested it out and it worked okay. Not the best approach, NextJS should document the ways to add css in somewhere.

Courbevoie answered 20/1, 2020 at 13:59 Comment(1)
amp-custom tag in style element as no effect so ever. it works without it, so it is redundant with @Ethan answer.Annmarieannnora
C
0

This worked:

const ampStyle = `h1{color:red;}`

<style jsx>{ampStyle}</style>
Carillonneur answered 12/7, 2022 at 10:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.