How to Build an E-Commerce Site with AMP (Google I/O’19)

[MUSIC PLAYING] BEN MORSS: Thanks for being
here so early in the morning to discuss AMP with us today. My name is Ben Morss. ALAN KENT: And I’m Alan Kent. BEN MORSS: We’re both
developer advocates at Google, where
our job is to help the web be more beautiful,
better for users, and also for developers. We’re here today to
talk about how to build an e-commerce site with AMP. First, we’ll discuss why this
could be a good idea, why make an e-commerce site using AMP. And then I’m going to show
off a working e-commerce site I’ve been building with a
couple of collaborators– Damien, who’s here today,
Antoine, and Garen. And then, finally,
Alan will show you a new approach he’s
working on that’s based on fully reusable components. So first of all, why? Why build an e-commerce
site with AMP? I mean, after all,
isn’t AMP known mostly for static sites for publishers? Well, I was looking at an
e-commerce site a few days ago, and the home page had
288 requests on it with 88 JavaScript files
and about 500K of CSS. This is for a pretty simple
home page with very little or no interactivity at all. This is common with sites
on the web, e-commerce sites especially. They have a lot of
code in many cases. They’re packed with JavaScript,
CSS, and large images. And unfortunately,
this can create pages that are slow and
not always great for users. Look at this guy over here. He’s using an e-commerce site,
waiting for things to load. It’s not loading. He’s been driven to drink
and take up smoking. His life is being shortened
by your slow site. So save this person’s life
and make your site faster. You’ve probably seen
data on this before. If you’re here, you’re probably
a sophisticated developer. You’ve seen the
numbers about why speed matters and the numbers
about conversion rates and bounce rates and so on. So I won’t repeat those things
for you today, except for one. The following
number is something which I think is really
relevant to every developer today and every user. The thing is that when you get
to a slow site, then the slow– sorry– isn’t that
an awkward moment? If you’re giving a
presentation on stage, your slide is still loading. It’s really an
unpleasant feeling. But even minus this context of
giving a presentation at I/O, just seeing this thing here– I get hives seeing this. I feel feverish and weak. We’re all conditioned,
I think, at this point, to see this beautiful,
interactive animated loading spinner not as a fun
feature, but as an annoyance. And if your user sees
this on your site, and he sees things
are spinning there for five seconds, sometimes
even 10 seconds, 15 seconds, they’re going to
go to their phone and press the button at
the bottom of the phone and do something else. Even on a desktop, these
things are annoying. So we know that speed matters. We want to fix speed. The thing is, the
problem is, that it’s kind of hard to do
that, even if you’re a good developer like yourselves
who has a lot of background and advanced techniques. It takes a lot of work,
a lot of knowledge, and also speed tends to regress. If you go to your
site and remove code, somebody will add code later on. If you remove large images,
people will add those later on. Speed tends to
regress over time. So you can do it,
but wouldn’t it be nice if there was a
framework out there that did the hard work for you? Well, that’s why
AMP was created– to make sites that are faster
and also easier to create. And this is why we’re creating
this AMP e-commerce site right now. AMP has expanded over the
years from this simple thing for static sites for publishers
to more of a full-featured web components framework. It can’t do everything, but
it can do a lot of things. It can power most of the kind
of content on the web today. And it wants to
make sites faster and more stable for users and
simpler for you, the developer. Plus, we’ve seen some big AMP
PWA e-commerce success stories during the last year or two. For example, in South Africa,
Superbalist over here– Superbalist turned some of their
highest-volume product pages to AMP, and they saw dramatic
increases in their metrics. Mobile bounce rate dropped,
conversion rates got better, and most notably, the
conversion rate for AMP pages was much better
than non-AMP pages. And this matters in places
where connection speeds for mobile phones are
slower, but it really matters everywhere in the world. Also, if you know AliBaba,
the very, very, very large Chinese company, AliExpress,
converted their mobile site to AMP about a year
and a half ago. And you know Singles’ Day? November 11th, where people go
online and buy a lot of stuff in China? They sold $31 billion of
stuff on Singles’ Day alone. So apparently, AMP works
well in production as well. So given all these
things, I want to try it, see what it was like,
and learn from the experience. Let’s consider, now, how we
did this and consider the goal of this kind of project. Let’s consider four key pages at
the start of the user’s journey to an e-commerce site. So let’s say Alan over here
is going to go to our site and buy something. So first of all, the home
page should load quickly because it’s often the
first page people get to from search or anywhere else. It should be responsive. It should have a nice menu. It should look beautiful. And also, it should
be customized, at least a little bit, to
Alan’s needs when Alan is done. If he’s gone to our site before,
added things to the cart, it should show that over here
on the top right-hand corner. Can AMP do this? Can AMP have that
dynamic thing that shows a number of items in the cart? Can it work on desktop devices? Let’s find out. Once Alan gets to the
home page, hopefully he’ll click on some sort of
category and arrive at our product-listing page,
also called a product list page. This will pull fresh
data from the server, and should allows Alan
to sort and filter his results over
here, and, of course, should work across all devices. Can AMP do that? Assuming AMP– assuming
Alan likes this– his name is not AMP,
his name is Alan– assuming Alan likes
this over here, he’ll click on a
product of some sort and want to customize
this product. He might want to choose
the color, the size. As he changes the
quantity over here, that should appear over there. As he changes the
color and the size, the number of items
available should also update automatically. How do all those
things work with AMP? And finally, Alan’s
going like this so much, he’s going to add it to his
cart and go to his cart page. This cart page,
of course, should be fresh and pull fresh data on
all devices and all browsers. And he should allow it
to go ahead and change things in the cart, to
remove items from the cart. And as he removes
items from the cart, the number of things and
the little run number should change automatically. So how do all these
things work with AMP? Well, before we discuss
the site itself, let’s discuss very briefly
what AMP actually is. We can’t discuss this
in much detail today, but essentially, AMP is
a web-components library. All of these things here are
a few of the web components that exist with AMP. AMP adds new tags to HTML. HTML was created around 30 years
ago as a document description language. So it’s full of things
like this is a paragraph. This is bold face. This is a header. It never had tags for
things like this is a menu. This is an image carousel where
images slide around the screen when you swipe them. This is a Twitter embed. Those things were not part
of the web a long time ago. So those things in
general, we create today with JavaScript, sometimes in
some cases, a little too much JavaScript. AMP adds these tags into
HTML via web components. These web components are run
by AMP’s own JavaScript, which is kept as small as possible. Conversely, AMP discourages you
from using your own JavaScript, except for in certain contexts
that makes things faster. You lose some customization,
but you gain a lot of speed. Now there is a new
component called amp-script that allows you
to write arbitrary JavaScript of a certain
size after user actions. So it doesn’t load– it
doesn’t run on page load. It runs after a user
action of some sort. We didn’t use this, though,
at this site so far. We found we didn’t actually
need that kind of JavaScript. Eventually, we’ll
probably do it, but so far, AMP components
have been enough to power the whole experience. Here’s an example
of how AMP looks. This is a component called
amp-youtube over here. You see, it’s pretty
easy to use these things. There’s a new tag in
HTML called amp-youtube. The layout type is responsive
in this case, which means that AMP
will automatically expand and contract the video
as this container expands and contracts. You give it the size in
advance because in AMP, you declare the size of all
the things in advance to ensure a stable layout
so that as your page loads, things don’t jump around. And finally, you
specify the video_id. And there it is, a YouTube
embed appears magically. If you follow the rules
that AMP sets out, you pass what’s
called AMP validation. And then your site is called–
or your page is valid AMP. So there are spiders
out there, web spiders like Google’s and Microsoft’s,
that are looking all the time for valid AMP pages. If your page is valid AMP, these
spiders will find it, mark it as valid AMP, and
your content will be cached on special
servers called AMP Caches. You can see over here an
example from Google search. Those lightning bolts over
there all indicate AMP articles. The thing in the
middle is amp-carousel, which is content from
publishers that’s AMP. And also, in certain
cases, your content might just be served
from Google’s servers, but it will be
preloaded in an IFrame. So when the user taps or
clicks on the results, it will appear
almost immediately. Also, Bing has AMP
results in search as well. And there’s examples from Bing– lightning bolts,
same kinds of things. AMP Caches are quite useful. They do involve some work
on your part sometimes. And here to discuss the AMP
Cache in more detail is Alan. ALAN KENT: Thank you for
remembering my name this time. BEN MORSS: It took
me a little while. ALAN KENT: So why do
we care about speed for an e-commerce site? It all boils down
to conversion rates. Faster sites do convert better. Now a lot of people
already use a CDM. CDMs are great to get the
content closer to the devices, which helps the content
to download faster. But how do you get
it to go even faster? There’s two techniques
that AMP Caches use. One is to be able to do
a background prefetch, to actually fetch the
content while the person is on the search results page. Another aspect they do is
actually optimize the HTML. And you can do things like
inline reference scripts and so forth. And you can do
that automatically. So let’s just look through
what a typical search session– the exact details change
from time to time, but the basic
principles are the same. So a user goes to
a search engine. They perform a search. They get their results,
and what happens is you want, in the
background, to start fetching. If that user– if
that browser starts prefetching from the origin,
from the user’s website, that’s a no-no because that’s
starting to leak privacy data. The website gets to know that
the user is doing a search. All they’ve done is looking
at the search results page. They haven’t clicked
on anything yet. And so the way to solve this
is to get a proxy in between by talking to the
AMP Cache instead. The AMP Cache goes and talks
to the origin, if necessary. And you never see, you
never get the information leaking through. The origin doesn’t know that
the user’s done that search. So when the actual user
finally clicks on the link, it appears instantly. There’s no network delay. There’s no rendering delay. All of this has been
happening in the background. Now it does a predictive
model normally. You don’t prefetch every single
page or every single link on the page, but you
can usually predict what the user is
going to click on, and you prefetch those ones. So one of the other
aspects, though, is once you’ve fetched
it out of the cache, and it’s got the Google
domain name on it, unfortunately, the
challenge, then, is when it actually goes
to fetch some other data, like trying to fetch pricing
data or other dynamic data from the site, it has to– it’s a cross-origin request. So it’s no longer coming
from the same domain name, and you just have to make
sure you set up some headers– from cross-origin request
headers and there’s some cookie headers to set as well. And once you get that set
up, it’s all good to go. So let’s keep having a
look at the application. BEN MORSS: Thank you very much. And just to add to that
there, as you know, also, signed exchanges
are now available on AMP, and they work in Chrome. Signed exchanges allow you
to use your own domain, even on an AMP Cache. So the considerations
with the cache will mostly go away as this
becomes more prevalent. For now, it does
require some extra work by you, the developer. So let’s look at
the site over here. If you want to look at the
site we’re making over here, it’s available at Look at it now or look at
it later because, of course, our talk is so exciting, you’re
at the edge of your seats. If you want to look at the code,
it’s over here at this special little go link here, After the talk, please
check out this code. Try it out. Make comments if you want to. Make pull requests. Copy it and use it
in your own site. We try to learn
how this work would work to inspire you to
make AMP sites of your own, using these techniques. So here’s our site. First of all, we started
with a good design. We began with a special template
that exists on, where there are premade
templates with HTML and CSS you can copy and use
yourself right away. This had no data, though. It was just a template. It’s just HTML and CSS. We had to make this
a live, real site. We had to use actual data. Fortunately, our friends
over at WompMobile, who make AMP PWS sites for a
variety of different sites, gave us access to
the API they created for a company called Campmor. And so thus it was
that we use their data and the bike shop
became a camping shop. So now, let’s go through
these four pages in the user journey– the home page, the
product-listing page, or product list page some people
might say, I’m told by Alan, the product details
page, and our cart page– and see how we did
these things, see how we solved the
various problems we encountered on the way. First of all, the home page. The home page is
pretty straightforward. It’s a pretty
static-looking site. It’s a classic example of
the more static content we’re used to seeing with AMP. It’s got a nice menu, nice
things like that going on. And the nice thing
about it, though, is it doesn’t have a lot
of CSS or JavaScript. It has very little CSS and
very little JavaScript. It’s mostly static, except for
things like menus and so on. But it is an
e-commerce site that has to have some things in it
about what the user has done. Let’s say, again, that Alan
has gone to the site before. Let’s say he’s gone there,
put things into his cart. Well, you can see in the
top right-hand corner a small number by the cart. That should show how many
things are in Alan’s cart. So how do we get that? Normally, we identify the user
by using a session cookie, and this is during
this case as well. So our goal is to get
the session cookie, send to the server. The server will then see what’s
in Alan’s cart and return JSON that will then let us
display that number up there. How does it work in AMP? Well, there’s little
circles there, indicating that special
number in that special cart. To do this we use
two AMP components that work very well together,
amp-lists and amp-mustache. Simply, amp-list does requests
to your server via XHR, and the data that comes back
from the server as JSON can get formatted and added to the
screen via a mustache template. Here’s how that
looks on our site. Amp-list up there, you see. You give it a source attribute,
which is, in this case, the API end point,
api/cart-count. And that will make the
API call that we need. And then inside, there is
this mustache template, which is pretty simple in this case. All it has is a count
of things in the cart. That little #count over there. It says that if nothing’s in– if the count is zero, this is
falsey, then skip all this. If it’s not zero, it’s
chewy, I guess you might say, and then the little span
there will get displayed. You see at the bottom the
JSON items count as one. And there you go. So if the user goes to
your site on your domain– in our case– this is very straightforward. But as Alan was
mentioning before, there is an issue with caches
if signed exchanges are not active. Because let’s say you’re
on Google’s AMP Cache. In that case, the user
actually is not on They’re actually
on So if the browser makes the
request from, [?, ?] that’s
cross-origin request, which will get blocked by any
kind of modern browser. Again, if signed exchanges are
enabled, this is not a problem. But until then, it could
be a problem for you. The fortunate thing is there’s
an easy solution for this. You simply have to
add CORS headers. CORS stands for Cross-origin
Resource Sharing, And you add some headers on
there, and there you are. So if your server sees a
request from a different domain, it checks a few things, It
adds some extra headers, and there you go. One handy tool to do this is
the handy-dandy AMP Tools Box– AMP Toolbox CORS
node module, which does most of the work for you. It basically adds
the AMP CORS headers if the request contains an AMP
source origin query parameter. To get more information
about CORS, just go to this documentation over
here, and you can learn more. This solves, in general, the
problem, but in some cases, though, we have a problem
because certain browsers will block third-party cookies. And if your user’s looking at on the domain, the cookies are from
a different domain and certain browsers are now blocking
third-party cookies. So how do you
solve that problem? Without the session cookie,
we can’t tell who Alan is. In this case, we simply
don’t display the number of items in the cart. If the user is curious
about their cart, and they tab or
click on that, it goes to the cart
page on their domain. It’s not a big deal anyway. It’s not a totally
ideal solution, but it’s a small
compromise to make. We think the cache is worth it. The cache has a
lot of advantages, and this is the one case
we couldn’t actually do a small feature in the
cache, but again, not a big deal in our opinion. Let’s move on now to page number
two, the product listing page. Somewhere else, if you’re
just make it through you from search, somewhere else
where speed is very important. So on this page
over here, Alan may wish to sort the items
over here and filter them in various ways. So how does it work with AMP? We’re going to use
amp-list again, plus another component
called amp-bind. So binding is similar to binding
and other JavaScript frameworks that you’ve used. It follows three basic steps. State, where you declare an
application’s state variable, using the amp-state components. And then, you bind
an event to an action that will occur if
the event happens. You also bind a
JavaScript expression that includes that state and
variable something in the DOM. So then, when you mutate, or
change the state variable, the expression will change,
and the thing in the DOM will change automatically. Let’s take a look at that. So here’s the state. In this case, we
have a state variable called products, defined using
the amp-state components. And again, all these things
here occur via HTML in AMP, which you get used
to after a while. The state variable
contains three things– gender, category, and filter. Note those things there
in angled brackets. And percent signs,
well, are the servers and– the server-side
rendered things, so they will just appear
simply to the client as things like female, and
the category of shorts, and so on and so forth. So there’s your state variable. Next, we bind an event
to this action over here. Notice this on
attribute that allows you to assign when something
changes a thing will happen. In this case, when user changes
what’s in the Select, high-low or low-high, then the value
of products will change and the filter will contain
either high-low or low-high. Those are the two
options over there. Finally, the mutation step. This is bound in a very
interesting and kind of novel way. Notice the amp-list
has the source attribute that we saw before. The source tells the amp-list
where to get data from, the end point to use. But ultimately, we have
a source in brackets. That is a bound attribute. It is bound to this kind of
complicated-looking expression in JavaScript. It’s actually pretty simple. It generates the
kind of things you see in the bottom right
in that little white box. So it simply will change
the API call [INAUDIBLE] when the query parameters
change– sorry, when the parameters change,
it adds new query parameters, and then there you are. It generates a new API
call automatically. So the whole thing
is when a user changes what’s in the
Select, the variable changes. This is the binding
changes over here. The expression changes, and this
triggers a call to our server. It pulls new data, and the new
items appear on the screen. It’s kind of a neat pattern. Once you figure it out,
pretty easy to use. And again, very
little JavaScript was written to make this work. So now the third step. Alan has gone to our home page. He’s gone over here
to our product lists page, or listing page, and then
he clicks on an actual product because he wants
to buy something. Yeah, we’re doing
so well so far. We go from there to our
product detail page. For this, we’ll focus on a
couple of interesting AMP techniques. First of all, the
products on this page may change pretty often. So our strategy is to
just pull these things from the server on page load. So use amp-list to do that,
and we cache these things for a few hours using Max
Age, and we’re all set. The thing is, though,
that we want to change a few things on the page. We want to pull the price
data here spontaneously. We also want to pull the
availabilities spontaneously. This is two different things. This would require two
different amp-lists because it’s two
areas of the page. But we want to avoid
making two server calls. It’s more efficient to make
one server call, of course, get all the data, and stick
it all on the page at once. So how does that work? How can AMP do that? What if you have three or four
or five things on the page? How does that work? Fortunately, oh, sorry, this guy
is here to say, “What do we do? Oh, no.” Well, fortunately, the solution
for that is pretty easy. It’s called XHR batching. AMP will intelligently
notice that there are multiple calls
to the same endpoint, and instead of doing it
twice, or three or four times, as long as they’re
occurring at the same time, it will do it once and use
the data from those things all at the same time. So here it is, the
network panel over here. We did these two
amp-lists we see over here in blue at the bottom,
only a single API call. Something else over here. We have the cart experience. This is pretty
simple in the origin. We submit a form,
the information about the user’s choice, and use
amp-bind to move things around on the screen, add and change
colors and change numbers– all pretty simple. Let’s look at how
that might look. So we’re going to use a
POST request over here. We send information to
add the cart because POST is more secure than GET. It might look kind of like this. There’s our Add To Cart
API endpoint over there. AMP adds a special header
saying AMP Same Origin is true if we’re on the same origin. So from your
[? mirrored ?] origin, it will add this header saying
AMP Same Origin is true. Also a session cookie gets
sent, and ID with what he wants to add get sent. There is the request,
sort of, in detail. Now, however, on the
cache, the AMP runtime will not add a special header. So it just has the cookie and
the product_id, but remember, there are certain
browsers out there that are blocking
third-party cookies. So in some cases, we
have no cookie at all. All we get is a request to add
something and the product_id, and no session cookie. So how do you add
to cart on the cache in the case there is
no signed exchange and third-party cookies
are being blocked? The cool technique for this,
fortunately, to the rescue, is a header called
AMP-redirect-to. We’ll see how this
looks over here. Essentially, the idea
is that what we’ll do is redirect the
user to the origin. At the origin, the
cookie is readable, and then we actually make the
change, and it all works out. It’s a bit elaborate, but
it works quite nicely. So here’s the
first step of this. Alan requests to add
something to his cart. So then AMP sees this request
and sends a POST request to our server,
saying add-to-cart. That’s the API endpoint, and it
requests a certain product_id to be added to the cart. So we realize in this case,
if there’s no cookies, then it means we
couldn’t read the cookie. If we’re not on
the same origin– sorry, if we are in the
same origin, in that case, cookies weren’t settable
on your origin, which means your person’s
browser is blocking Javascript cookies in general. We can’t do much about that. So we’re not going to try
add to the cart at all. If you’re blocking
cookies, then most sites aren’t going to work anyway. But if there are no cookies, and
the same origin header is not set, it means that
we’re on the cache, so use the following
technique in this case. We send back your response
that says AMP-redirect-to and say redirect to the
cart page, in this case, with, as a query parameter,
the requested mutation. So we’re going to redirect
back to our origin with the product_id equals
123 as a query parameter. AMP then sees the
AMP-redirect-to header, and then it sends
a redirect request to the server over here. And there is– there now– we
have that query parameter there with product_id in it. And now that we’re on the
origin, the cookie can be read. So this is good. We have a session cookie. We can then, in the server,
look in the database, see what Alan’s cart
contains, make the change, make the add to the cart. And we’re going to do
one final redirect, which is to redirect to the origin
minus the query parameter because the query parameter
doesn’t look good. If you refresh [? it ?]
[? to ?] the browser, it might do it twice. These are all not good things,
so we do a final redirect. The result of this is
we’ve moved from the cache to the origin, read its
cookie, and made the change. From now on, on your
origin, on your own domain, and all future interactions
will be simple. This is kind of an
elaborate pattern, so we’re writing up a series
of guides on things like this. Please look for these
guides and on in the near future
for these techniques. OK. One final page over
here, the cart page. We’ve gotten to
the cart, and we’ll see how one final interaction
works on the cart over here. Before that though, once
again, we have the cache issue. If we’re on certain browsers
that are blocking cookies, and those [? signed ?]
exchange, once again, we can’t read this cookie,
and we’re: kind of stuck. The problem is this is
an interactive page. The cart contains fresh
data, so we can’t really cache this page anyway. So actually, why cache this
page in the first place? Why cache somebody’s cart page? It’s dynamic anyway. And how often do you
get to a cart page from search, in any case? Not very often. So our approach over
here is not to have the cart page cached at all. It shouldn’t be on the
cache in the first place. There’s two ways to do this. One is introduce the
trivial validation area. [? It’s ?] a trivial
validation error in AMP, like you’re moving this
lightning bolt over here, and then the AMP
web crawlers out there will not see the page as
valid AMP and won’t cache it. Perhaps the easier
solution is just to not include it in robots.txt. So that you tell robots.txt
to have crawlers not crawl this page and not
cache it in the first place. Now onto the
interaction over here– how to remove things
from the cart. This involves all the
things you’ve seen so far– amp-list, amp-bind,
and amp-form. We’ll do this briefly because
our time here is limited, but our cart is
built by amp-lists because the cart is dynamic. So when the user
goes to your page, amp-list should pull fresh data,
the cart data, from the server. So amp-list does that. Also notice that we
have a binding up there. We have source-this-cart items,
our API for pulling items out of the cart, but also, we
have this binding to the state variable, cartItemLists.items. So as the user makes
changes, our approach is tell the server
the change was made. The server then sees the change
was made, makes the change, and sends back JSON with
the new cart items in it. And then amp-list
will refresh the cart. That way, when the
user makes the change, they don’t see it on the
screen until it actually has happened in real life. So the way this works is
the user clicks a button. And when the button
gets clicked, then the product_id gets set,
the itemToRemove variable, and then we automatically submit
the form-cart-delete form. So again, we set a variable,
application state and variable, to what he wants to remove. Then we submit a form. That form is over here. That form sends up
product_id to the server, and hidden input over here. The server makes the change. The server sends
back items that are in the cart after the change. That gets sent to us
in the event response. Now cart-items-lists is bound
to the actual items in the cart, and on submit-success over here,
that gets set [? to that ?] variable. And then, like
magic, the amp-list will see it there,
look back at the top. There’s that bound source
attribute over there, and then it will stick
the current cart_items into the cart. And again, sort of elaborate. Check out the code, and
[? we’re ?] writing guides about these things as well. So there’s a lot about
how we actually made various interactions work
and made the cache work. Now onto the build process. A build process is
always important. It makes your life
easier as a developer and lets you have cleaner code. In this case, our
build is pretty simple. We take advantage of a couple
of important node modules. For one, amp-html-autoscript. This came out of this project. Our friend, Garen,
made this over here. This, essentially, will
automatically find what components are being used on
each HTML– on amp-html pages, and then insert the appropriate
JavaScript automatically because each AMP component– most AMP components
use JavaScript, and this will insert
those things in there automatically for you. We also use AMP Validator. This is a pretty
important component. It allows you to make
sure your pages are valid before you actually
send them to GitHub or print your code. So as part of your
build process, you validate your pages,
thereby ensuring your pages are always valid. And it’s nice because instead
of setting performance budgets, and doing more things to make
sure your sites are performant, you just follow the
rules of AMP and AMP pretty much ensures that without
certain things you might do, your pages will be fast. Finally, one more thing I
can talk about over here. AMP wants you to put all of
your CSS within style tags instead of in an external file
to save a network request that can block rendering. Of course, mixing HTML
and CSS is kind of ugly, so I recommend always building
your CSS in a nice process somewhere else,
and then sticking into the style-amp-custom
tag once you’re done. Our process here is very simple. We have a series
of partials here. We have various
partials that are used throughout
different kinds of files, different kinds of
each HTML pages, and put those things
together over here. This is pretty straightforward. But wouldn’t it be easy and
nice if we could actually, instead of doing this, we could
bundle a little more than that? What if we could also
go further than this and give you a high-level
library of components you could use? Higher than AMP components,
which contain their own CSS, and can be reused
across different sites? Fortunately, Alan is working
on just this right now. ALAN KENT: Thanks, Ben. So the purpose of
this library is we’ve been creating
a set of examples of our common
e-commerce platforms. So I’ll have the CSS. I’ll have the AMP markup. So the whole idea is to so you
can copy and paste and then get your project
together a bit quicker. So just to run through
some different page types. If you’ve got a page type–
though Ben’s mentioned four page types– there’s a lot more than four. I saw one list that had
25 different page types. And so we’ll include some
examples of some common page types. There’s also some examples
that span across pages, headers and footers and so forth. The component library,
we’re also together through common e-commerce
platform– patterns. These are the main ones
that are really interesting. And so an example might be
you mark up one set of screens and then you want to
say, “Oh, well, instead of having an add-to-cart flow,
I want to try a buy-now flow.” And so you just drop
in different components onto the page to assemble it. We also need to include some
really low-level presentational buttons. Unfortunately, there’s lots
of other libraries around, but they’re not
always guaranteed to be AMP compatible,
so we’ll be including some of the low-level
functionality as well. So to do this so you can
actually take these components and use them, we’re going
to be using Next.js. There’s a number of
benefits to Next.js. There’s lots of React
developers out there. It’s a good component framework. It’s got good CSS support
for various tools already. But most importantly,
they’ve recently launched native AMP support. So if you just get Next, you can
get AMP going out of the box. But it is important to
remember that even though React is very popular, there are
lots of libraries out there that are built on client-side
rendering of React, and we’re not using
those capabilities. So you can’t use all
of the React libraries out there, unfortunately. We’re just using
its capabilities for server-side rendering pages. So let’s have a look
at a couple of pages. Here is an example page. It is actually the home page of
exactly the same site as what Ben built. I just took
it and componentized several [? of the ?] contents. And you can see it just
inputs all the components. It loads them up, and
you’re up and going. So that’s an example of a page. The only special
thing we had to do was to add this
with AMP function what this function
does is it intercepts certain URL parameters. You can actually have both
optimized AMP and native AMP, the valid AMP on the same
page, and this library just does all the work for you. So that’s the only work
we really had to do, was to add a with-AMP
function into the pages. Going on to– now, we’re
having a look at one of the components on that page. This one the idea is
we’ve picked up– this is doing the header at
the top of the page. You can see the bit
of the graphic there. It’s picked up at TopNavBar
component from a library, so you just– we’ve
reused that one. It shows it trying to make
it generic so you reuse. You might have to set the middle
and the right attributes there . So you can either
just, for the middle, we just had another component
and we referenced that one. For the right, we’ve actually
embedded markup directly on the page. But there’s also little things
you can do like pass arguments into these templates. In this case, we’re
going to show the cart count if you’ve set an
attribute on that previous page. So in the markup
you can actually control what the
component will do. This one is then having a
look at that cart count, what we were looking at before. It’s using an amp-list,
pretty much as before. Now both AMP templates
and React use braces, so you’ve got a
little bit of magic to do the [? scaping, ?]
but it’s not too bad. Now one of the things
that AMP supports– Next.js supports,
sorry, that just makes assembling these
pages a little bit easier is is this head element. And what it will do is
it include the script, but by having that
key attribute, it removes duplicates. So you can throw a whole lot
of components onto a page, and you’ll get exactly the right
list of includes in the head. It will automatically get
rid of any duplicates. It just makes it easy. You just throw a page together. You can also have the CSS
straight in the same component, which is just convenient. Next.js has got support. And again, it– if
we have a look at how all of goes together,
what Next.js will do is it walks the componentry,
identifies all the components, collects all the
CSS and inlines it into one unit in the
head, as required by AMP. It’s all done for you. And it also collects all the
script references for you and puts it in. So you can try it. We haven’t got very far on
the component library yet. We’re beginning some
of the infrastructure. But I’ve got basically the
home page up and going. The components I
show are working. It’s on that Git
repository there if you want to grab a look. So where are some of
the future directions we’re heading with AMP? There’s amp-script is
particularly useful. It’s not fully released
yet, but it’s certainly available for those
who want to try it out. It allows you to design your
own components, for example, so you’re not limited to what
AMP supplies out of the box. AMP Experiment 2.0 is coming. It’s got a lot better,
A/B testing support, so you can get that built
straight into your site. There’s lots more components
coming all the time. Some have arrived recently. We’ve got infinite scroll,
input masking, recapture, but there’s lots more coming
in terms of like autocompletion and so forth. And a really important
one has been mentioned is signed exchanges. That solves some of the
cookie problems on the cache. So why would you use
AMP for e-commerce? To me, the number one
reason is search speed. There is data showing that if
you get that little icon bolt, users start to learn
that that means speed. And especially on a
slow device, people are more likely to
click those links. And so you can get
more traffic from it. But AMP also helps with your
page speed, UX best practices. You can have highly interactive
pages with amp-list. Personally, I really
like the simplicity. Your pages are back
to declarative markup. You’re just dropping on tags. You’re not [? writing ?]
code or through the pages. The pages are more
maintainable, and putting AMP throughout your
site saves having to do sort of dual
development of your pages. Back up to you, Ben BEN MORSS: Thanks a lot, Alan. So to learn more about all
these things, go to, where you can find
documentation, interactive playgrounds to
try out various components, links to this site over
here, for example, tutorials, and some new free coursework. So try it out. We think you’ll like it. Some things might be
useful for you– again, over there. There again is the URL of our
site,, a link to the, code, and other
random stuff on there that got there for some strange reason. That’s all we got. Go try it yourselves. Tell us what you think. ALAN KENT: Thank you. BEN MORSS: Thank you very much. [MUSIC PLAYING]

, , , , , , , , , , , , , , , , , , , , , , , , ,

Post navigation

4 thoughts on “How to Build an E-Commerce Site with AMP (Google I/O’19)

  1. How to solve Google webmaster AMP error like "The tag 'meta charset=utf-8' appears more than once in the document"

    I used AMP Native mode

  2. AMP is still incredibly buggy and not useful across multiple browsers. I'm really upset that I can't build a fluid AMP site without being a knowledgeable developer getting paid and having countless hours available. mustache and list are not functioning well. Even on Newegg's AMP site, their sliders glitch between images or skip images in the carousel. I should be able to build a website without AMP's strict specifications, and so long as it follows general guidelines it should be able to show on Google's results as an AMP site and be loaded in Google's cache. Really hating AMP.

Leave a Reply

Your email address will not be published. Required fields are marked *