Next.js: with-amp example is not pass AMP Validator

Created on 23 Oct 2017  路  9Comments  路  Source: vercel/next.js

Because of AMP restriction, it does not allow custom script,
But the server rendering include custom script of next.js, so with-amp example is not pass AMP Validator.
Can we remove those scripts ?

Thank you.

Most helpful comment

There are two problems:

  1. <meta charset="utf-8" /> appears twice (solution: remove this line)

  2. The attribute 'as' may not appear in tag 'link rel='.

To remove the as attribute from Next.js scripts you can do the following:

Add a _head.js file into /pages directory (like _document.js).

In this file you should extend Head and copy 3 methods from main class:

// _head.js
import { Head } from 'next/document'

export default class MyHead extends Head {
  getChunkPreloadLink (filename) {
    // remove as='script' in return statement
  }

  getPreloadDynamicChunks () {
    // remove as='script' in return statement
  }

  render () {
    // in return statement remove as='script' from <link rel='preload'... lines
  }
}

// you should redeclare this function because is not exported
function getPagePathname (pathname, nextExport) {
  if (!nextExport) return pathname
  if (pathname === '/') return '/index.js'
  return `${pathname}/index.js`
}

getPagePathname function has to be declared again because is used by the render method.

Finally, you should change _document.js and import the extended class MyHead:

// _document.js
import Head from './_head'

The AMP validation is successful but you get a warning:

<link rel=preload> must have a valid `as` value`

Here is a discussion about this warning from the AMP Project repo.

image

This is the solution that I've found, probably it's not the best, and it should be reviewed 馃槈.

Related: #2310

All 9 comments

There are two problems:

  1. <meta charset="utf-8" /> appears twice (solution: remove this line)

  2. The attribute 'as' may not appear in tag 'link rel='.

To remove the as attribute from Next.js scripts you can do the following:

Add a _head.js file into /pages directory (like _document.js).

In this file you should extend Head and copy 3 methods from main class:

// _head.js
import { Head } from 'next/document'

export default class MyHead extends Head {
  getChunkPreloadLink (filename) {
    // remove as='script' in return statement
  }

  getPreloadDynamicChunks () {
    // remove as='script' in return statement
  }

  render () {
    // in return statement remove as='script' from <link rel='preload'... lines
  }
}

// you should redeclare this function because is not exported
function getPagePathname (pathname, nextExport) {
  if (!nextExport) return pathname
  if (pathname === '/') return '/index.js'
  return `${pathname}/index.js`
}

getPagePathname function has to be declared again because is used by the render method.

Finally, you should change _document.js and import the extended class MyHead:

// _document.js
import Head from './_head'

The AMP validation is successful but you get a warning:

<link rel=preload> must have a valid `as` value`

Here is a discussion about this warning from the AMP Project repo.

image

This is the solution that I've found, probably it's not the best, and it should be reviewed 馃槈.

Related: #2310

Thanks so much @ismamz
That's work

Another problem I am facing is using styled-jsx in AMP.

styled-jsx will render many tag <style id='__jsx-xxxx'>..</style> which is not allow on AMP.
AMP only allow 1 tag <style amp-custom>...</style> on the page

can we combine all css to <style amp-custom> with styled-jsx ?

You can add the amp-custom attribute to <style> tags generated by styled-jsx, and you can even combine all the CSS code. Look at your _head.js file, the render() method takes the styles array and you can manipulate them.

However, there are some problems: 1) styled-jsx will add class names to custom amp tags and it's not valid, 2) you are intervening the way of work of styled-jsx.

So, maybe styled-jsx is not the best option for an AMP site in this case.

I'm going to close this as we're going to make some changes to better support AMP soon.

@timneutkens thanks for the update. Looking forward to AMP changes soon. We have AMP templates and trying to migrate those to Next soon.

@timneutkens Great! we hope to receive news soon about an excellent integration of AMP with NextJs :smiley:

Any news on AMP support here?

@ismamz I'm currently working on AMP with ReactJs, is there a way to have custom attributes in square brackets such as [class] with reactJs on client side as well. As of now, reactJs when re-render all the custom attributes gets eliminated.
Also tried using react-amphtml, but same happened with AmpHelpers.Bind

@varungargofb Hi!, I think that this is not a Next.js related question.
But, the only way I found to use that kind of attributes is setting inner HTML.
For example, if you want to reproduce the example from the amp-bind docs:

<div dangerouslySetInnerHTML={{__html: '<p [text]="\'Hello \' + foo">Hello World</p>'}}/> 
<button on="tap:AMP.setState({foo: 'amp-bind'})">Say "Hello amp-bind"</button>

Other ways like using React.createElement('p', { '[text]': "'Hello ' + foo" }, 'Hello World'); or el.setAttribute('[text]', "'Hello ' + foo"); doesn't work.

I hope that helps you.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sospedra picture sospedra  路  3Comments

YarivGilad picture YarivGilad  路  3Comments

irrigator picture irrigator  路  3Comments

formula349 picture formula349  路  3Comments

kenji4569 picture kenji4569  路  3Comments