Next.js: Next.js 8.1 AMP + Styled Components example does not work

Created on 17 Apr 2019  路  3Comments  路  Source: vercel/next.js

Overview

Using the with-styled-components example running Next v8.1.0, it does not work using withAmp. Here is the error:

TypeError: styles.map is not a function
    at Head.render (/Users/lrobinson/Developer/personal/with-styled-components-app/.next/server/static/development/pages/_document.js:1174:26)
    at processChild (/Users/lrobinson/Developer/personal/with-styled-components-app/node_modules/react-dom/cjs/react-dom-server.node.development.js:2959:18)
    at resolve (/Users/lrobinson/Developer/personal/with-styled-components-app/node_modules/react-dom/cjs/react-dom-server.node.development.js:2812:5)
    at ReactDOMServerRenderer.render (/Users/lrobinson/Developer/personal/with-styled-components-app/node_modules/react-dom/cjs/react-dom-server.node.development.js:3202:22)
    at ReactDOMServerRenderer.read (/Users/lrobinson/Developer/personal/with-styled-components-app/node_modules/react-dom/cjs/react-dom-server.node.development.js:3161:29)
    at Object.renderToStaticMarkup (/Users/lrobinson/Developer/personal/with-styled-components-app/node_modules/react-dom/cjs/react-dom-server.node.development.js:3661:27)
    at renderDocument (/Users/lrobinson/Developer/personal/with-styled-components-app/node_modules/next-server/dist/server/render.js:95:18)
    at Object.renderToHTML (/Users/lrobinson/Developer/personal/with-styled-components-app/node_modules/next-server/dist/server/render.js:238:16)
    at <anonymous>

Which is from overriding _document.js to make styled-components work:

import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
  static async getInitialProps (ctx) {
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
        })

      const initialProps = await Document.getInitialProps(ctx)
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        )
      }
    } finally {
      sheet.seal()
    }
  }
}

To Reproduce

npx create-next-app --example with-styled-components with-styled-components-app

Modify index.js

import React from 'react'
import styled from 'styled-components'
import {withAmp} from 'next/amp';

const StyledTitle = styled.h1`
  color: red;
  font-size: 50px;
`;

const Title = () => <StyledTitle>My page</StyledTitle>;

export default withAmp(Title);

Then, run yarn dev and you will see the error.

System Information

  • OS: macOS
  • Version of Next.js: v8.1.0

Most helpful comment

I believe that with this approach, styled-components-injected styles will be in a separate <style> tag, which is against AMP specification. Is there any downside to merging styles like this?

const initialProps = await Document.getInitialProps(ctx)
return {
     ...initialProps,
     styles: [...initialProps.styles, ...sheet.getStyleElement()]
}

That seems to work without any issues

All 3 comments

I believe that with this approach, styled-components-injected styles will be in a separate <style> tag, which is against AMP specification. Is there any downside to merging styles like this?

const initialProps = await Document.getInitialProps(ctx)
return {
     ...initialProps,
     styles: [...initialProps.styles, ...sheet.getStyleElement()]
}

That seems to work without any issues

Similar problem using withSass. Is not compatible with AMP mode 馃槙

Can confirm that it does not work with basic styled components implementation.

Was this page helpful?
0 / 5 - 0 ratings