Google’s Accelerated Mobile Pages (AMP) project is an of very fast HTML Web components that can help us build very fast websites, very quickly. open source library It’s been around since late 2015 and is very much a work in . Evolving and growing daily, with ambitious plans for the future and a team of over . constant progress 500 contributors It’s also , that if we follow, mean that will cache our pages on their very fast CDNs. And when a mobile user searches for one of our pages Google will even begin partially prefetching it, giving near-instant page loads. a set of rules Google Example user flow illustrating how AMP pages can load almost instantly We’ll cover the fundamentals of AMP, view a snapshot of some components that are currently available and see how we can build the rich, interactive websites we want while still following the rules. Where to begin We write AMP in HTML but in order to do so we must first include the scripts for the components we want to use. AMP — “Fast by default” At its most basic, we just need to include the ~77kb AMP runtime script in our document’s (line:5 below) and then we’re able to use a few basic, built-in AMP components, such as (line:10–11 below). <head> <amp-img> The bare bones HTML needed to load the AMP runtime and use a built-in component Output of above HTML The AMP runtime provides the platform for the other AMP components to run on and also manages resources - lazy loading everything. And this component provides the required interface to load up images. <amp-img> For all the other components we also need to include their respective libraries. For example, if we wanted to use (line:15–23 below) we would need to include its script (line:6–7 below). <amp-carousel> Example of auto-playing carousel Output of above HTML That alone gives us the ability to use the multitude of AMP components and to build very fast websites, however, if we also want to harness the power of the AMP cache and Google search prefetching then we need to follow the rules. The rules 1 — Boilerplate There’s some mandatory boilerplate. Below is what it actually looks like on the page, specifics can be found in the . official Getting Started docs Bare minimum valid AMP HTML boilerplate 2 — HTML While most HTML is allowed, some tags that could slow down or block loading of the page are . prohibited or have amp replacements Replacement tags include:======================<img> => <amp-img><video> => <amp-video><audio> => <amp-audio><iframe> => <amp-iframe> Prohibited tags include:========================<frame><embed><style> => With exceptions<script> => With exceptions 3 — CSS Our custom CSS must be contained in one internal tag (line:5–9 below) that does not exceed 50kb, does not use and also follows . <style amp-custom> !important some other CSS rules amp-custom CSS style tag To allow for bulky CSS keyframe animations there is also a . [<style amp-keyframes>](https://www.ampproject.org/docs/fundamentals/spec#keyframes-stylesheet) tag that can be up to 500kb 4 — JavaScript The tag can only be used to store data (state). It can also load AMP libraries but it can’t be used for any custom . So, unfortunately, JavaScript breaks the rules and is prohibited… for now. <script> JavaScript Video of what’s allowed by the AMP rules If we can abide by we have a which will be cached in the Google CDN and prefetched for Google mobile search users. while developing, in CI/CD and in production. these rules valid AMP page Validity can be checked A page that doesn’t follow all the rules but still uses some AMP features is called a by some, it will still work fine and be very fast but won’t get the other benefits of AMP. dirty AMP page The restriction on custom JavaScript has a huge impact for web development and is enough to put some people off, but AMP solves too many problems and is gaining too much popularity to ignore, with over 4 billion AMP pages from over 25 million domains including the who’s who of top-tier websites being reported in early 2018. These restrictions aren’t there just for a laugh or to annoy developers, or even more sinisterly to try and control the web as far as I know. All this is being done to put the , so that we build better web experiences, sacrificing . User first everything else that gets in the way of that mantra “Do what’s best for the end user experience “— https://www.ampproject.org/about/amp-design-principles/ It’s not time to throw everything else we know about web development out of the window just yet but it is worth taking on AMP as another very handy tool in our toolbox. A tool that does give us ways to do of what we want. So, let’s get a taste of some of the components and implementation patterns. most Layout AMP is a little obsessive about knowing where things go on the page and what their dimensions need to be without having to fetch resources. Layout makes two appearances: A that knows how to size itself and what its pixel dimensions or aspect ratio will be. It’s a built-in component of the AMP runtime. multipurpose container component And an that lets individual components know how to do the same. AMP-HTML attribute They have a and depending on the type of layout, and may or may not be required, and can act as pixel dimensions or aspect ratios. If no is present, AMP will try to infer it based on the presence of and . helpful collection of values width height layout width height These not only ensure minimal time is spent rendering the page in the client for the user but also give us developers a nicer API to size elements or containers, giving gains over writing responsive CSS. Take the examples below: We use an component with to create an element that fills all available space, it’s green just to show its bounds. <amp-layout> layout="fill" Next we have an component with a (line:1 below) to make an element with a fixed height of 200px. It will take all available width, and is yellow. <amp-layout> layout="fixed-height" height="200" Within that component we have an example of the attribute on the component (line:2 below) that just scales the size of text to the requested size, in our case we have set so it takes all the room of its parent. layout <amp-fit-text> layout="fill" Finally, a responsive with an aspect ratio of 1.6 by 1. <amp-img> If we put that all together here’s what it might look like: Output of above examples of layout Templating AMP has an via mustache.js ( ), the key features as laid out in the official docs are: <amp-mustache> component that allows logic-less templating mustache docs : A variable tag. It outputs the the HTML-escaped value of a variable. {{variable}} : A section tag. It can test the existence of a variable and iterate over it if it's an array. {{#section}}{{/section}} : An inverted tag. It can test the non-existence of a variable. {{^section}}{{/section}} doesn’t work on its own, it must be used as the templating solution within a parent that can get data from a CORS JSON endpoint, such as . <amp-mustache> <amp-list> Take this example template that uses an to get iterable data from the and to display each iteration: <amp-list> Star Wars API <amp-mustache> (line:4 below) writes out the value of the attribute from the returned response array. {{name}} (line:7–9 below) the variable holds a value so it is treated as a conditional, the within is only rendered if exists. {{#url}} <a> url (line:12–18 below) returns an array so it is treated as a loop, within which we have chosen to nest another CORS JSON endpoint in an so we can get the names of the films each character has appeared in. (line: 13 below) represents the value of that item in the array. {{#films}} <amp-list> {{.}} Example of iterating over JSON and templating the response Output of above amp-mustache and amp-list example Media components Aside from which we’ve already seen, there are replacements for , and others. While , resources like these can also automatically gracefully degrade when you supply a cascading set of s for it to filter through (line: 20–21 below). <amp-img> audio video most components can have a [fallback](https://www.ampproject.org/docs/reference/common_attributes) and [noscript](https://www.ampproject.org/docs/reference/common_attributes) tag <source> Example media components, with fallback and alternative sources There are also many proprietary components that make it easy and fast to load content from sources such as YouTube, Instagram, Twitter, Imgur, Hulu, Soundcloud, etc. Here we use a layout component called to cycle through and display several media components. <amp-carousel> Example of various media components in a carousel Output of above example of media components Actions and Events The element attribute provides us a means to trigger actions on user events. Implementation follows the below pattern: on on="event:target[.action[(...args)]]" 1 — event is the name of the event that the element listens for. The event is available on all elements and is the most straightforward way to implement a click event listener. Elements individually expose other useful events relevant to them such as . event tap change, submit, input-debounced 2 — target is the DOM #id of the element to trigger the action on. It can also call the AMP runtime itself via to do things like . target AMP navigateTo(), setState() 3 — action is the optional method to trigger on that element. It’s optional because elements have default actions. All elements have some common actions such as and element specific ones such as . action() toggleVisibility(), scrollTo() submit(), open(), close(), toggle() 4 — args are optional key=value pairs, e.g. . args 'name'=event.value In the following example we create a which is by default (line:3 below), a with a event that targets the by its and toggles its visibility (line:1 below). Within that is another tag with an action (line:6 below) that takes us to a URL. section hidden button tap section id section AMP.navigateTo And finally, an (line:9 below) that will scroll to (line:13–15 below) in however many milliseconds we input after a built-in 300ms debounce on the event. input #my-image input-debounced Examples of actions and events Output of above example, showing scroll duration determined by input value You can read more about . AMP actions and events in the official docs Dynamic components We’ve already touched on and which gives us ways to retrieve and display JSON data dynamically. We could also use to submit form data or make XHRs. <amp-list> <amp-mustache> <amp-form> There are also some very handy components such as that gives a really great API and UX for date picking and that lets us vary content based on geolocation. <amp-date-picker> <amp-geo> We can also serve up unsupported interactive content, including JavaScript, in an . can’t be in the top 75% of the initial viewport or 600px, whichever is smaller. And they do not have access to the parent window outside of sending a . <amp-iframe> These iframes postMessage amp-iframe interactive embedded google maps iframe component JavaScript enabled google maps iframe amp-bind But really, the big one here is . Bind enables data-binding and expressions, it was released in to the wild in 2017 and represents a substantial jump forward for AMP. It allows : <amp-bind> State, Bindings and Expressions 1 — State The via hard coded JSON or a CORS JSON endpoint. We can define multiple mutable state objects. setting and getting of state Examples of valid amp-state State can be updated via the action. E.g. . We can also use instead to add a new entry in the browser’s history stack so when our user navigates back they will restore the previous value of state. AMP.setState() AMP.setState({state: {'name':'Chewbacca'}}) pushState() 2 — Bindings between component/element properties and state. There are some bindable attributes common to all elements, e.g. and a host more that are specific to individual components, e.g. . Create data bindings height, width, text, class src, srcset, alt, placeholder, value, href In the below example the of the will dynamically update from . We can reference state by its #id. Bindings only update after user action. text h1 state.name [...]= After user action the default text will be updated with whatever is in state.name When bindings start to get too verbose or we want to make them reusable we can employ to . <amp-bind-macro> create callable expressions Example of amp-bind-macro creation and consumption 3 — Expressions , using a . These expressions can reference the document’s but not the itself or . Writing that can reference our state expressions subset of JavaScript state document window Below, on the event of this button, we create a new state object with an #id of and use an expression to create an endpoint for a random Star Wars character. tap remoteState Example of using expressions If we put that all together it could look something like this: An example using state, binding and expressions Output for above HTML Video introduction to amp-bind Presentation components We have components like which outputs a nicely formatted time difference, and which formats mathematical formulas but the star here is . <amp-timeago> <amp-mathml> <amp-story> allows the easy creation of magazine or digital storytelling formats with rich media and animation capabilities built in. There are extra features built in too for common magazine layout requirements. <amp-story> Example of magazine article built with amp-story It’s optimised for mobile devices in portrait mode. In landscape it gives a warning to rotate back to portrait and in wider viewports such as tablets and desktops it doesn’t expand responsively or adaptively. Non-mobile experience for amp-story There is an optional bookend after the last page which can have social media links, other relevant links, and call-to-action buttons. They may be statically generated or come from a JSON endpoint where some scope for customisation exists. Example bookend for amp-story What are people doing with AMP Here are some more examples of live AMP pages that use the components and strategies laid out above, and many more. AliExpress Evening Standard Resources We’ve just dipped our toes in the pool, if you like the temperature then here are some resources: Official website — https://www.ampproject.org Github repo — https://github.com/ampproject/amphtml/ Loads of examples for all components — https://ampbyexample.com AMP playground — https://ampbyexample.com/playground/ Starter templates — https://www.ampstart.com/ Official codelabs — https://codelabs.developers.google.com/ Thanks! Thank you very much for reading. If you have any feedback or questions please get in touch here on Medium or on . twitter @sanj9000 If you’re in London, UK then come along to one of our , and if you’re looking for a great place to work then we’re ! AMP meetups hiring great people