How to Use Nuxt AMP Module to Create Accelerated Mobile Pages
April 22nd 2020
Accelerated Mobile Pages (AMPs) are a syntax format for web pages to create fast, performant websites that are optimized for mobile users. AMP pages are similar to static site generated pages such as those generated by Gatsby.js or Nuxt.js in that they are optimized for performance, but they have very apparent differences. The biggest difference is that AMP pages have specific html format that needs to be adhered to in order for the page to be considered an AMP. Also, to ensure small page sizes, AMP format does not allow JavasScript (outside of the one required external JavaScript file which includes and loads the AMP JS library). Because of these differences, AMPs are going to look quite different than their static generated cousins. So why would you want to use AMPs over SSG pages?
Benefits of AMP
The greatest benefit of accelerated mobile pages is going to be the fact that the AMP project is backed and endorsed by Google themselves. This means that they support the AMP standard and we do know that speed, security and mobile accessibility are very large search ranking factors. All together, AMP pages are going to rank higher in search results because of their page speed and security and the syntax format endorsed by Google and other search engines.
Using the Nuxt AMP Module
Previously, before the official @nuxtjs/amp
module we had to do a lot more work and had a lot fewer options to generate AMP pages using Nuxt. This required you to hook into Nuxt lifecycle events and run regular expressions on the outputted HTML to change them into AMP pages. Fortunately, the @nuxt/amp
module does a lot of the heavy lifting for us and provides a lot more options such as the mode
option which allows us to identify if we want pages to be generated as both AMP pages and regular Nuxt pages. It also provides the ability for us to specify a custom layout for our AMP pages so we can create a more simple layout or change out our navigation for an AMP compatible componentshttps://amp.dev/documentation/components/ in our layout. Speaking of components this is another benefit of using the @nuxtjs/amp
module as it detects AMP components inside pages and injects the required AMP JavaScript Files for those specific components.
Installing the Nuxt AMP Module
Installation for the module is simple. All you need to do is navigate to your nuxt project and you can use your package manager of choice to run:
yarn add @nuxtjs/amp
//or
npm i @nuxtjs/amp
Now with our dependency installed we can open our nuxt.config.js
to add it to our modules
array:
module.exports = {
modules: [
'@nuxtjs/amp'
],
amp: {
//module options here
}
}
The @nuxtjs/amp
module gives us options that we can include at a global module level and some options can be added/overriden at the page configuration level.
Nuxt AMP Configuration
One of the first configuration options we want to set at the module level is the origin
property. The origin property is the main domain of the nuxt site and is used to create the canonical link for pages the hyrbid pages that have both amp pages and regular site pages. The canonical link in AMP is used to ensure you don’t have duplicate content and Google and the other search engines can serve the AMP pages for mobile experience but can also index and serve the regular page when necessary. We are going to use an environment variable to set the origin
property. First, install the dotenv
node package to use inside our nuxt.config.js
by running:
yarn add dotenv
//or
npm i dotenv
require('dotenv').config()
module.exports = {
modules: [
'@nuxtjs/amp'
],
amp: {
origin: process.env.ORIGIN_URL || 'http://localhost:3000'
}
}
Now we’re able to create a .env
file and add our ORIGIN_URL
such as:
ORIGIN_URL="https://example.com"
Now when AMP generates hybrid
pages such as a page found at ./pages/about.vue
each page generated will have a <link>
tag with the appropriate rel
attribute such as:
This link tag will be added to the to the non-AMP page:
<link rel="amphtml" href="https://www.example.com/amp/about">
And this to the AMP page:
<link rel="canonical" href="https://www.example.com/about">
The next option we can look at adding to our amp
module options is the mode
property. This property allows us to identify if we want our nuxt pages to be generated in a hybrid
mode which generates both AMP versions of the page and non AMP versions. If we want all of our pages to be served as AMP we can use the only
option. The mode
option defaults to hybrid
as that is what most Nuxt projects would want.
Default behaviour of amp module. (
https://github.com/nuxt-community/amp-module/blob/master/docs/api/options.mdonly
all pages serve in AMP mode by default,hybrid
pages serves in both normal and AMP mode,false
pages does not serve AMP by default )
require('dotenv').config()
module.exports = {
modules: [
'@nuxtjs/amp'
],
amp: {
origin: process.env.ORIGIN_URL || 'http://localhost:3000',
mode: 'hybrid', //could use `only` or `false` as well
}
}
Finally, we can explore the routeAliases
option. If your app uses AMP only on a few routes you can provide those routes into an Array. Routes are absolute, without ‘/amp’ prefix, eg. ['/about', '/contact']
. This would specify the routes that you want to use to generate as AMP pages. Note, that the routeAliases
option does not work for dynamic routes such a dynamic page route found at /pages/post/_id.vue
etc.
Nuxt AMP Page Configuration
With the @nuxtjs/amp
module installed you have a few options at the nuxt page level that are available to set within the nuxt page component. The two options that you have here are: amp
and ampLayout
. The amp
option allows you to override the mode
option specified at the module level. For instance, if you have your mode set to hybrid
but you know that you do not want one of your pages to be generated as an AMP page you can set the amp: false
within your page export such as:
<template>
<div>
<h1>Not an AMP Page</h1>
</div>
</template>
<script>
export default {
amp: false
}
</script>
This will ensure that your page will not contain an AMP counterpart. Lastly, you can set the option for ampLayout
which will specify which layout the amp generator should use to generate the amp page. This option is recommended because AMP pages more than likely will need to be customized to remove JavaScript functionality in your header/footer/sidebar components that are typically included in your default nuxt layout. Instead, these components can be replaced by the appropriate AMP Component and included inside your ampLayout
component.
Creating AMP Layout in Nuxt
It is recommended to create a special layout for your AMP pages. The @nuxtjs/amp
module makes this easy with the ampLayout
property on the page level. This allows us to use AMP Components within our AMP Layout. Let’s say we create a layout at ./layouts/amp.vue
which could look like:
<template>
<amp-body>
<amp-sidebar id="sidebar1" layout="nodisplay" side="right">
<ul>
<li>Nav item 1</li>
<li><a href="#idTwo" on="tap:idTwo.scrollTo">Nav item 2</a></li>
<li>Nav item 3</li>
<li><a href="#idFour" on="tap:idFour.scrollTo">Nav item 4</a></li>
<li>Nav item 5</li>
<li>Nav item 6</li>
</ul>
</amp-sidebar>
<Nuxt />
</amp-body>
</template>
<script>
export default {
}
</script>
<style>
@import "~/assets/styles/default.amp.css"
</style>
There are a couple important key points in the layout that we created. First, we are using the <amp-body>
which is required for the use of specific AMP components such as the <amp-sidebar>
component. We are also moving the imported default.amp.css
out of our nuxt.config.js
and importing it into our <style>
tag inside our layout. It’s recommended that you do this for both your AMP Layout pages and your non AMP Layout pages so as not to include any css globally in the nuxt.config.js
file.
However we recommend to create a separate style file for AMP pages and import it in AMP layout, also remove styles from
https://github.com/nuxt-community/amp-module/blob/master/docs/guide/styling.mdnuxt.config
and import those files in default layout instead.
AMP Components
As mentioned previously, the AMP syntax offers custom components that allow us to add functionality, interactivity and design to our AMP pages (since we are not allowed to use any JavaScript outside of the AMP scripts). The @nuxtjs/amp
module detects if components are included within a page and adds the required corresponding amp script to our final page output. To see a list of amp components that the module supports you can consult the AMP elements page to see if the component is supported.
https://github.com/nuxt-community/amp-module/blob/master/docs/api/amp-elements.md
@nuxtjs/amp
automatically detect AMP elements inside page and inject required scripts.
Conclusion
The @nuxtjs/amp
module is a great utility for us to create AMP pages in our Nuxt.js module. It allows us to define pages that we want to generate as both AMP pages and regular Nuxt pages. We can create and define a specific layout for AMP pages to include AMP components, in which the module will include the required AMP scripts for us in our rendered pages. Enjoy creating high performant, fast and secure pages using the AMP protocol in your Nuxt project!