Accelerated Mobile Pages, or AMP, is an open source web components framework that increases the speed of loading webpages. AMP imposes strict guidelines on the HTML, CSS, and JavaScript of a webpage, controlling how external resources like media, ads, and other scripts are loaded.
In this tutorial, we’ll navigate through some of AMP’s guidelines, learning how to manage some of the trade-offs that arise. We’ll cover how to display resource-consuming elements on a webpage while still adhering to AMP’s rules by using AMP components in a Next.js project.
If you wish to follow along, all of the code for this tutorial is available on my GitHub. Let’s get started!
AMP optimizes webpage loading by preventing developers from using custom elements that include resources like images, video, and audio. Similarly, developers can’t write custom JavaScript for tasks like displaying dynamic ads, embedding social media posts, and creating interactive forms. To work around these limitations, we’ll use AMP components.
AMP components are custom-written pieces of HTML that we can use to add complex features to our webpage while still remaining compliant with AMP’s standards.
Currently, the AMP component catalog includes built-in components for many common tasks, like adding images, calculating webpage analytics, and displaying ads. Because built-in components are included in the base library of AMP, you don’t need to include them explicitly in your code.
Extended components are extensions to the base of the library and are not included by default. In your code, you’ll need to include extended components explicitly as custom elements. For example, you may wish to add page analytics with amp-analytics
or add a lightbox with amp-lightbox
.
The catalog also includes experimental components, which are released but not yet supported for wide use. If you can’t find what you need in the component catalog, you may wish to write your own AMP component!
Now that we know what AMP components are available, let’s add one to a webpage!
Before we can add an AMP component to our webpage, we’ll need to configure our webpage as an AMP page. The amp
configuration accepts two types of values, true
and hybrid
. Entering a value of true
turns the webpage into an AMP HTML page. Entering a value of hybrid
creates two versions of the webpage, one in AMP HTML and one in standard HTML, with standard HTML as the default.
Let’s configure our webpage as an AMP page with true
:
export const config = { amp: true }
Now, let’s create a true AMP page by running the code block below:
export default function Page = () => { return <h1>My First AMP Page</h1> }
When we export the true AMP page, Next.js will create two versions of the page: an optimized version for your users and an unoptimized version for search engines.
To create a hybrid AMP page, all you have to do is change the configuration value of the page to hybrid
:
export const config = { amp: 'hybrid' } export default function Page = () => { return <h1>My First AMP Page</h1> }
To visit the AMP page, you’ll need to add ?amp=1
to the end of the URL. Additionally, because hybrid
isn’t a Boolean value like true
, you’ll need to surround it with quotes.
Hybrid AMP pages require you to write valid HTML for both AMP and standard HTML pages. To render the correct HTML, we can use the useAmp
React Hook.
useAmp
React HookAdd the useAmp
React Hook to your webpage by importing the package below:
import { useAmp } from 'next/amp'
Next, create a variable that saves the output of the React Hook:
const isAmp = useAmp()
Now, you can use either a ternary operator or an if
statement to render the correct HTML:
{isAmp ? ( // AMP component ) : ( // Standard HTML ) }
Finally, we’ll put everything together! In the example below, we’ll use amp-img
, an AMP component that loads images, to display an image on our webpage:
import { useAmp } from "next/amp"; import Image from "next/image"; export const config = { amp: "hybrid" }; export default function Hybrid() { const isAmp = useAmp(); return ( <div> <h1>Hybrid AMP Page</h1> {isAmp ? ( <amp-img alt="A view of the sea" src="/chiangmai.jpeg" width="640" height="360" ></amp-img> ) : ( <Image alt="A view of the sea" src="/chiangmai.jpeg" width="640" height="360" /> )} </div> ); }
In the AMP version in the example above, we don’t have to use the default HTML <img>
tag. Additionally, because amp-img
is included as a built-in component, we didn’t have to import it into our webpage! If a component from the AMP component library is not included in the base library, we’ll receive the following notification that it requires an external script:
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.2.js"></script>
In Next.js, you’ll need to include this script
tag in the head of your document, as seen in the code block below:
<Head> <script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.2.js" ></script> </Head>
Before we export our AMP page, let’s make sure it meets AMP’s requirements. There are plenty of methods for adding validation, for example, npm packages, command-line tools, browser extensions, and the developer console! Let’s take a look at the built-in method for AMP validation in Next.js, amphtml-validator
.
During building and exporting, amphtml-validator
requires that AMP pages meet the AMP specification. Any warnings or errors will be displayed in the terminal.
For example, let’s say that you try to use a regular HTML <img>
tag instead of amp-img
. It will result in an error on export, as seen in the code below:
Amp Validation /hybrid?amp=1 error The parent tag of tag 'img' is 'div', but it can only be 'i-amphtml-sizer-intrinsic'. error The parent tag of tag 'img' is 'div', but it can only be 'i-amphtml-sizer-intrinsic'. > Build error occurred Error: AMP Validation caused the export to fail. https://nextjs.org/docs/messages/amp-export-validation
If you want to use a custom AMP validator, you can add the path to your custom validation rules in the next.config.js
file:
module.exports = { amp: { validator: './custom_validator.js', }, }
If there are no validation errors, running next export
will export all of our pages to static HTML pages. Next.js automatically detects if a page supports AMP and exports the page in the correct format.
As mentioned earlier, a hybrid AMP page will be exported as two files. For example, say we have a hybrid page called pages/blog.js
. It would be exported as out/blog.html
, a standard HTML page with a client-side React runtime, and out/blog.amp.html
, an AMP HTML page.
Next.js will automatically insert a link from the AMP page to the standard HTML page, and vice versa, as seen in the following two code snippets, respectively:
<link rel="amphtml" href="/blog.amp.html" /> <link rel="canonical" href="/blog" />
If pages/blog.js
were a true AMP page, it would export a single HTML file called out/blog.html
.
Now, you know how to get started with AMP components in Next.js!
In this tutorial, we covered built-in, extendable, and experimental AMP components, true and hybrid AMP pages, and the useAmp
React Hook. Then, we learned how to validate and export AMP pages in Next.js.
At the time of writing, AMP only supports CSS-in-JS for styling. However, support for CSS Modules is being developed, and you can find some workarounds on GitHub.
Similarly, there is no official support for TypeScript. Although it is on the roadmap, there is no scheduled release date yet. As a workaround, you can create a file with custom types called amp.d.ts
inside your project and add custom types for AMP.
I hope you enjoyed this tutorial! If you find yourself stuck, leave a comment, and I’ll do my best to help you out.
Debugging Next applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Next.js app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your Next.js apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to implement one-way and two-way data binding in Vue.js, using v-model and advanced techniques like defineModel for better apps.
Compare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
One Reply to "Adding AMP components to a Next.js webpage"
I am using it with app router but it is not working , can anybody help me.