How to Make a Basic AMP Page From Scratch

By April 27, 2016 How To's, Mobile, Website
  • The AMP Project is a newly deployed open source initiative backed by Google, with the goal of helping make sites faster, particularly those with heavy use of media and/or need for monetization. It’s essentially a “no fuss” way of rolling out what could otherwise be somewhat complex optimization methods, with most of the processes taken care of behind the scenes for you.In our article AMP Project: Will it Make Your Sites Faster?, we get into detail on what AMP will mean to you from a developer point of view, and give you some raw numbers on what kind of speed gains AMP may or may not give you.

    In this tutorial we’ll be more practical, with a step by step guide for actually creating an AMP page from scratch, explaining how to do some common tasks the AMP way, and sharing some tips as we go.

    Let’s begin!

    Adding standard boilerplate code is where every AMP template starts. There is a set of code that must be present in every AMP template, or it will fail validation.

    Create a new HTML file named index.html and add the following code to it:

    You can read a breakdown of each element of the above code at:

    You can (if you choose to) preview your newly created AMP template by opening it up directly in a browser. However it’s always a good idea to preview on a localhost instead. This approach simulates a web host, so the environment you are previewing your template in is as close as possible to the live environment it will be deployed to.

    For this purpose, I recommend using MAMP for Windows or Mac. If you don’t already have MAMP installed, head to the MAMP website and download a copy.

    Once you have MAMP installed, find its htdocs folder. On Mac you will typically find it at/Applications/MAMP/htdocs, and on Windows at C:\MAMP\htdocs\.

    Inside it, create a new folder to house your project, e.g. myproject. Then move the index.html file you created in the previous step into the folder.

    Run MAMP and you should now be able to preview your AMP template by going to the URL http://localhost:8888/myproject/ in Chrome. Even if you prefer another browser, please use Chrome as we’ll be using Chrome Developer Tools in the next step.

    Your AMP page should currently look like this:

    If you go to this URL and it doesn’t work, it’s possible MAMP may be running on a different port number to the 8888 you see in the URL provided above. To find out if this is the case, on the MAMP interface click the button that reads Open WebStart page. This will take you to a page with information on MAMP, and in the URL you’ll see the correct port number to use instead:

    Before we go any further, we want to turn on AMP’s debug mode so if we accidentally do something that doesn’t pass validation we’ll know about it right away.

    To do this, add #development=1 to the end of your preview URL, e.g. http://localhost:8888/myproject/#development=1.

    Then open up Chrome Developer Tools and go to the Console tab, where you should see the followingPowered by AMP HTML… message appear:

    As you develop your page, if anything doesn’t pass AMP validation you’ll see an error message in the console. Right now we have no error messages and instead see “AMP validation successful”, letting us know everything is working as it should be.

    Along with the boilerplate code you already added, you have the option to add some JSON metadata to the head section in format like so:

    This is not essential to pass AMP validation, but it is essential in order to be picked up by various places such as Google Search News.

    To read more about this metadata visit:

    One of the requirements of AMP is that all custom CSS should be placed inline in the head section, between <style amp-custom>...</style> tags.

    Despite this requirement, actually writing your CSS straight into the head section is not an ideal workflow. What you really need is to be able to write your CSS in an external stylesheet, as you normally would, then have that CSS moved into the appropriate place in the head sections of all your site’s template files.

    We won’t be covering the step by step of how to do this here, but if you would like to know how to use an external stylesheet and still pass AMP validation, please follow the steps in our quick tip tutorial Make AMP’s Inline CSS Easier via Jade or PHP before proceeding.

    Now that you have your essential code in place, development mode activated, and (optionally) external stylesheet management ready to go, we can now move on to adding some media to your page. We’ll start with the most common type of media: images.

    In AMP you don’t use the <img> tag to load images. Instead you use the custom element <amp-img> as it will handle loading optimization across all the images in your page.

    From here on in the tutorial, we’re going to be working with an existing template design to help speed things along. Go ahead now and grab yourself a copy of the free Ceevee template by StyleShout. This template includes some images you can use to practice embedding into your AMP document.

    In the Ceevee templates images folder you’’ll see a large image of sand dunes at night. We’re going to start by placing this into your template. Copy the images folder and paste it into your project folder.

    Then, add the following code to embed the image, above the h1 tags that are already in the HTML:

    Any form of media placed into an AMP page must have an initial width and height set, so unlike using animg tag, in an amp-img tag you cannot leave these attributes out.

    If you’re not sure exactly what size an image will be it’s okay, as long as the values you enter accurately represent the aspect ratio. The width and height values can be considered as placeholders, as AMP can layout the page with the values you provide and then make adjustments after the image is fully loaded.

    The layout attribute is what allows AMP adjust the image’s display after it’s loaded. We have set its value to responsive, meaning that it the image will maintain the aspect ratio derived from the width and height values, but shrink or expand to fill its container. This is why even if you don’t know an image’s exact size, as long as you have the aspect ratio you’re good to go.

    Save and refresh your preview and you should see the image filling up your viewport:

    Read more about amp-img and the layout attribute at:

    A common element in web design today is the use of a background image that fills the height and width of the viewport, creating something of an entry presentation for a page. Typically this is done using a background image with the CSS background-size: cover; applied to it. However in AMP sites we don’t really want to bring in large background images via CSS as this would bypass the system’s loading optimization.

    Now, you could certainly make the argument that loading a large background images isn’t ideal for boosting load speed, and for that reason you may be better off leaving large images out all together.

    However, if you unavoidably need to create a design with a large, full viewport image you can still at least tap into AMP’s loading prioritization by adding it via the amp-img tag instead of as a background. Here’s how you can do so, approximating the background “cover” technique in the process.

    We’re going to take the image that you just embedded and turn it into a cover image. First, wrap the image with a div tag using the class doc_header so you have:

    Then, if you haven’t already, add some <style amp-custom>...</style> tags to the head section so we can include some custom CSS. In between those tags add:

    Usually, instead of what you see above, when creating a cover image a designer will set the height of thehtml and body elements to 100% and then also set their cover section to a height of 100%, making it fill the viewport.

    However this approach will not work with AMP as the CSS it loads enforces the style height: auto!important; on the body element, preventing a setting of height: 100%; from working.

    So instead, if you really need something to be the height of the viewport you can use height: 100vh;, as we’ve done with our doc_header class. The vh unit represents “viewport height”, and a value of 100vhequates to 100% of the viewport height.

    If you save and refresh your site now you should see that the “doc_header” div fills the viewport exactly.

    At the moment though, the image doesn’t necessarily fill the “doc_header” div. If the viewport is taller than it is wide, there will be a blank black area below it.

    To fix this add the class doc_header_bg to your amp-img tag like this:

    Then add to your CSS:

    This code will ensure that the image height is never any less than that of the viewport.

    Unfortunately, it will still get squashed at narrower widths so it is not as elegant in appearance as using a background image. However, it is as close an approximation as we can get whilst still using the amp-imgelement.

    Now we’re going to add some custom web fonts into our template. When doing this with AMP you have three loading methods that will pass validation:

    Loading a Google Font should be done via a link element in the head, using the URL provided to you for the font(s) you want at

    For our template we’ll be using Open Sans and Libre Baskerville.

    To load these two fonts add this code to your head section:

    We’re now going to add some text to our site cover area, to which we’ll apply our new web fonts. Inside the existing “doc_header” div, under the image, add a new div with the class doc_header_inner:

    Inside that div add the following code:

    Now add the following to your custom CSS:

    The code above is just regular CSS for the purposes of laying out our newly added text, however you’ll notice that the process of applying our Google Fonts in an AMP template is no different than usual. You use the font-family property with the value of your chosen font, e.g. font-family: 'Libre Baskerville';

    On saving and refreshing your site you should see both Google Fonts now applied to the text in the cover section:

    Next up we’re going to add a custom font that isn’t available from either Google Fonts or, and that’s Font Awesome. Often, if you’re using Font Awesome you might load it up via MaxCDN, however AMP won’t allow this as the CDN is not one of the two approved font origins. As such, we’re going to handle the loading ourself via @font-face.

    In order to load the font yourself you’ll first need to download the font files, which you can do at Note you only need “Font Awesome”, not the extra “FortAwesome” tools that are offered during download.

    Once you have the Font Awesome zip file downloaded, extract it and copy the fonts folder it contains into your project folder.

    To your CSS, add the following code:

    I recommend inserting the above code at the top of your custom CSS to help keep things organized. This code loads in our custom font files and creates classes that can be used to add font icons to a design–it’s the standard CSS provided for use by Font Awesome.

    Then also add this CSS:

    This extra CSS adds some styling specific to our template that we’ll use to setup a row of linked social icons.

    Add this HTML after the <hr> inside the “doc_header_inner” div:

    If you refresh your site now you should see a row of @font-face powered social icons along the bottom of the text we added earlier:

    To help ensure visitors don’t end up seeing a broken site if custom fonts don’t load successfully, AMP provides the amp-font element to allow you to create fallbacks.

    To make this element work the first thing you’ll need to do is load the AMP script that enables it. In your head section, add this code:

    Now with the amp-font element ready for use, we can have it add a class to the html or body tag if our font fails to load. Add this code to the bottom of your template, before the closing </body> tag:

    Let’s take a quick look at the attributes set in this element. We first set layout="nodisplay" which ensures the element is invisible.

    Next, the attribute font-family is set to FontAwesome, which tells AMP we want to track the loading of the font named “FontAwesome”. Make sure this value exactly matches the font-family setting in your @font-face CSS code.

    The attribute timeout is set to 3000, which means we’ll allow up to three seconds for the font to load before moving to a fallback. You can change this to whatever value you prefer.

    Finally, we set on-error-add-class to font-awesome-missing. If the font fails to load after three seconds this class will be added to the html or body element. We can target this class to create our fallback behavior by adding this code to our custom CSS:

    If the font fails load after three seconds the above CSS will activate and hide the entire social icon bar so we don’t have any broken looking display.

    Now try temporarily renaming your project’s fonts folder so the fonts fail to load, then refresh your page and you should see the social icons area become hidden. You should also see the class font-awesome-missing added to the html or body tag. Restore the fonts folder to the correct name and you should see your font icons again on refresh.

    Read more about the amp-font element at:

    Next up, we’re going to learn how to add a YouTube video the AMP way, but first we need to add a little housekeeping code to create a section for the video to sit in.

    After the “doc_header” div, replace the existing h1 tags with this HTML:

    Then add this to your custom CSS:

    You might have noticed in the above CSS we set box-sizing: border-box; in the standard_padding class.

    The reason for this is in AMP you can’t use the common technique of including * {box-sizing: border-box}, because the * selector is deemed too resource hungry. As such you’ll need to set box-sizing: border-box; for the specific elements you need it on, or just handle padding and borders the old fashioned way–with a calculator or counting on your fingers.

    Now that the section is set up and ready for content, we’re going to add a YouTube video using AMP’s custom amp-youtube element. By using this element instead of standard YouTube embed code we can tap into loading optimization techniques similar to those of amp-img.

    To begin with, you’ll need to add the AMP JavaScript required to enable the new element. In the head section, paste in:

    Now add the following HTML inside the divs you just added, under the h2 tags:

    To specify the video you want to load, set its YouTube ID on the attribute data-videoid. Other than this attribute, the amp-youtube element is much the same as the amp-img element.

    We have the width and height set to 600 and 270 respectively. Just as with images, videos must have an initial width and height set.

    We then use layout="responsive" so that the video will fit the size of its container, while keeping the aspect ratio drawn from its height and width settings.

    Save and refresh your site, and try resizing the viewport. You should see that your YouTube video expands or shrinks to fit, keeping the correct aspect ratio as it goes.

    Read more about the amp-youtube element at:

    AMP has additional custom elements for loading content from specific sites, like amp-twitter, amp-instagram and a few more. For content from third party sites that don’t have their own dedicated AMP element, there’s the amp-iframe element instead. We’re now going to use this element to load a Google Map into our page.

    Create a container for the map by adding this code below your “video_wrap” divs:

    Now, as with the amp-font and amp-youtube elements, we’ll need to load the AMP script that drives the amp-iframe element. Add this to your head section:

    Next, inside your new div and under the h2 tags, add this code:

    Reload your site and you should see a Google Map now in place.

    As well as optimizing loading, using the amp-iframe element helps to ensure that the content being viewed through the iframe doesn’t behave in unwanted ways, such as executing JavaScript that might cause slow loading or forcing popup ads. The sandbox attribute allows you determine what level of control you apply over iframe content.

    For full details on amp-iframe and its “sandbox” controls, visit:

    One of the things that can feel limiting when working with AMP is the rule that no custom JavaScript is allowed. On the flip side though, there are custom elements included in AMP that aim to provide you with some of the functionality you might usually implement via custom JavaScript.

    For example, instead of loading a custom lightbox script you can use the amp-image-lightbox element. We’re going to create an image gallery that uses this element now.

    Start by creating a container for your gallery by adding this code right above your amp-font tag:

    Also add this to your custom CSS:

    Like our last few custom elements, we’ll need to load an AMP script to enable the amp-image-lightboxelement. Add this to your head section:

    Now we’re ready to start setting up our lightbox gallery. Start by adding this code inside your new divs, under the h2 tags:

    This amp-image-lightbox element will create the actual lightbox display with the enlarged images inside it. We want to hide it until a user has clicked an image they want to enlarge, so we set it tolayout="nodisplay".

    Note: we have set the ID of this element to lightbox1.

    To add an item to the gallery, add this div below the amp-image-lightbox element:

    Then inside it add this amp-img code:

    For the most part, this amp-image element is the same as the one we added earlier, however you’ll notice the addition of on="tap:lightbox1". This tells AMP that when the image is tapped/clicked, the larger version should be opened up in a lightbox with the id lightbox1, i.e. the amp-image-lightbox element we just created.

    Add another seven images to the gallery with this code:

    When you save and refresh you should see a gallery on your page that looks like this:

    And when you click any of the images you should see it open in a lightbox like this:

    To read more about amp-image-lightbox visit:

    You now have a basic AMP page with some of the most common types of content in place, and a few little tricks to help you work efficiently and in keeping with AMP’s rules for validation.

    Let’s recap the key points of what we covered:

    • Always start with boilerplate code
    • Use a localhost preview; MAMP recommended
    • Turn on debug by adding #development=1 to your preview URL and watching the Chrome Developer Tools console
    • Include JSON metadata if you choose
    • Handle inline CSS more easily via this Quick Tip
    • Use AMP custom elements instead of default HTML elements where available
    • Where required, load extra AMP JavaScript to drive custom elements
    • Load custom fonts from Google Fonts, or via @font-face, using the amp-font element to create fallbacks
    • Use in built AMP custom elements instead of custom JavaScript, e.g. amp-image-lightbox instead of a lightbox script

    I hope this all helped to clarify the process of creating AMP pages so that you feel confident to build live sites from scratch. Now get out there and have fun making AMP accelerated websites!

    Take a look at some of these landing page templates if you’d like to practice on something other than the one in this tutorial:

Source: TutsPlus

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.