Geolocation with amp-list

Edit on Github
Open in Playground View Demo

Introduction

If you need more fine-grained geolocation support than provided by the amp-geo extension, you can implement geo-based features with geolocation logic on your backend and amp-list. This adds an additional XHR request but you can mitigate the negative UX effects with a skeleton layout in the placeholder attribute.

Setup

Import the amp-list component ...

<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>

... and the amp-mustache component

<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>

Geo-based Search Results

amp-list makes a request to a server backend which does IP-based geolocation and returns relevant search results. For this demo, it calls an API to get nearby cities. The backend returns JSON results which amp-list renders with amp-mustache. The backend makes two remote API calls (and also adds 500ms of simulated delay); to mitigate the UX effects of this delay we use amp-list's placeholder to lay out a skeleton.

Since we need to have an initial fixed-size for amp-list we manually calculate that each card is 100 + 15px margin and the title is 16px + 20px margin:

16px + 20px + (5 * (100 + 15px)) = 611px

The placeholder list items largely use CSS to draw the skeleton elements as described in CSS-Tricks. The skeleton includes a tiny blurred map to add to the realism, and that map is also used while <amp-img> loads the actual images to prevent a flash when the placeholder is removed.

Example

You are in

<amp-list class="geolist-preview"
  width="auto"
  height="611"
  layout="fixed-height"
  noloading
  src="https://caramel-wolf.glitch.me//location-specific-results.json"
  single-item
  items=".">
  <template type="amp-mustache"
    id="amp-template-id">
    <p class="title">You are in {{location}}</p>
    <ul class="results">
      {{#results}}
      <li>
        <amp-img alt="{{placeName}} Map"
          noloading
          layout="fixed"
          width="150"
          height="100"
          src="https://maps.googleapis.com/maps/api/staticmap?markers={{lat}},{{lng}}&zoom=9&size=150x100&maptype=roadmap&key=AIzaSyByT-0aYa-nEF0gGqJHNpEEK1bus00losI">
        </amp-img>
        <p>
          <strong>{{placeName}}</strong>
          <br> {{adminName1}}
          <br> {{countryCode}}
        </p>
      </li>
      {{/results}}
    </ul>
  </template>
  <div placeholder>
    <p class="title">You are in
      <span class="placeholder"></span>
    </p>
    <ul class="results">
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>
  </div>
</amp-list>