Dynamic Fragments
Edgemesh Server Dynamic HTML Fragments for Mostly Cacheable Content.
For most content, Edgemesh Server will work without any code modifications and the page experience will be accelerated via intelligent edge caching. For fully dynamic pages such as carts and accounts, Edgemesh Server knows that the page can not be safely cached and accelerated and instead goes to the server directly for a server rendered experience.
But what if you have a page where 99% of the content can be safely cached but a single section requires some dynamic server side logic? It would be a shame (and massive performance loss) to allow this 1% of dynamic content to prevent the page from being cached.
Throwing an entire page from being cache-able due to one component is painful
To combat this, Edgemesh Server allows you to selectively serve sections of HTML without caching using the data-em-async HTML attribute. We call this Dynamic Fragments, a simple change developers can make to content to let Edgemesh Server know to cache most of the site, but intelligently fetch the dynamic content from the server without suffering a performance penalty!

Basics

Let's say you have a page with a server-side rendered variable on your / route such as:
1
<!-- simplified -->
2
3
<!DOCTYPE html>
4
<html lang="en">
5
<head>
6
<meta charset="UTF-8">
7
<meta http-equiv="X-UA-Compatible" content="IE=edge">
8
<meta name="viewport" content="width=device-width, initial-scale=1.0">
9
<title>My Store</title>
10
</head>
11
<body>
12
<div class="title">My Store</div>
13
<div class="welcome">Welcome {{ customer.name }}</div>
14
<ul>
15
<li><a href="/product-1"><img src="/product-1.png" /></a>
16
<li><a href="/product-2"><img src="/product-2.png" /></a>
17
<li><a href="/product-3"><img src="/product-3.png" /></a>
18
</ul>
19
</body>
20
</html>
Copied!
This full HTML would not be cacheable due to the templated customer name. The cached response would contain the name of the customer that initially cached the response and subsequent cached responses would be inaccurate. Enter Edgemesh Server Dynamic Templates.
The first step would be to serve the dynamic content on its own page. In the case of our example, you would make a new route that serves the dynamic content. Lets call it /welcome and it would contain the following template:
1
<div class="welcome">Welcome {{ customer.name }}</div>
Copied!
Then we will update our main HTML with the Edgemesh Server Templating to fetch the dynamic content from the client-side.
1
<!-- simplified -->
2
3
<!DOCTYPE html>
4
<html lang="en">
5
<head>
6
<meta charset="UTF-8">
7
<meta http-equiv="X-UA-Compatible" content="IE=edge">
8
<meta name="viewport" content="width=device-width, initial-scale=1.0">
9
<title>My Store</title>
10
</head>
11
<body>
12
<div class="title">My Store</div>
13
<span data-em-async="/welcome" />
14
<ul>
15
<li><a href="/product-1"><img src="/product-1.png" /></a>
16
<li><a href="/product-2"><img src="/product-2.png" /></a>
17
<li><a href="/product-3"><img src="/product-3.png" /></a>
18
</ul>
19
</body>
20
</html>
Copied!
Replace any dynamic HTML with an element with the data-em-async attribute where the value is the URL to the new page fragment we have just created. Edgemesh Server will then detect those tags and replace them with a client-side fetch and replace. When all is said and done the client-side HTML will be:
1
<!-- simplified -->
2
3
<!DOCTYPE html>
4
<html lang="en">
5
<head>
6
<meta charset="UTF-8">
7
<meta http-equiv="X-UA-Compatible" content="IE=edge">
8
<meta name="viewport" content="width=device-width, initial-scale=1.0">
9
<title>My Store</title>
10
</head>
11
<body>
12
<div class="title">My Store</div>
13
<div class="welcome">Welcome John Doe</div>
14
<ul>
15
<li><a href="/product-1"><img src="/product-1.png" /></a>
16
<li><a href="/product-2"><img src="/product-2.png" /></a>
17
<li><a href="/product-3"><img src="/product-3.png" /></a>
18
</ul>
19
</body>
20
</html>
Copied!
The HTML element with the data-em-async attribute is completely replaced with the content from the page fragment we created earlier. No extra elements will be injected and the resulting dynamic content will not be cached by Edgemesh Server.
In most cases, its best to try to move these dynamic features to the client side via REST endpoints, but where that is not possible Edgemesh Server Dynamic Fragments for the win.

Shopify Example

To demonstrate a more real-world example, let's take a server-side rendered Shopify pop-out cart and render it using Dynamic Fragments.

Find and Isolate Dynamic Content

The first step is to locate the dynamic content and isolate it into its own section if it isn't already.
/sections/popout-cart.liquid
1
<div class="popout-cart-container">
2
{% if cart.item_count > 0 %}
3
<h1>Cart</h1>
4
<form action="/cart" method="post" novalidate class="cart">
5
{% for item in cart.items %}
6
{% endfor %}
7
<footer class="cart-footer">
8
<p class="cart-subtotal">
9
<span class="cart-subtotal-title">{{ 'cart.general.subtotal' | t }}</span>
10
<span class="cart-subtotal">{{ cart.total_price | money }}</span>
11
</p>
12
<div class="cart-actions">
13
<button type="submit" name="checkout" class="btn">{{ 'cart.general.checkout' | t }}</button>
14
<button type="submit" name="update" class="text-link txt--minor">{{ 'cart.general.update' | t }}</button>
15
</div>
16
</footer>
17
</form>
18
{% else %}
19
<div class="text-center">
20
<h1>{{ 'cart.general.title' | t }}</h1>
21
<p class="cart-empty-message">{{ 'cart.general.empty' | t }}</p>
22
<p class="cart-cookie-message">{{ 'cart.general.cookies_required' | t }}</p>
23
<p class="cart-continue-browsing">{{ 'cart.general.continue_browsing_html' | t }}</p>
24
</div>
25
{% endif %}
26
</div>
Copied!

Create a Page Template

Next, create a page template for your cart fragment. Set the Create a new template for dropdown to page and the template type to liquid. Let's name the template popout-cart.
Creating a page template for the dynamic fragment.
Now that the page is created, we can add our section. Make sure to add the liquid directive {% layout none %} so that your page does not include any layout code.
templates/page.popout-cart.liquid
1
{% layout none %}
2
{% section 'popout-cart' %}
Copied!

Create an Empty Page with New Template

Next, go to Online Store > Pages and create a new page for your fragment. Set the title popout-cart, set the template to the template we just created popout-cart and leave the body blank. Publish the page and check to see if it's working by going to https://yourstore.com/pages/popout-cart. You should see the content from the popout cart section we created without any styles.
Creating a custom page for the dynamic fragment.

Replace Liquid template with Dynamic Fragment

Finally, we can replace the liquid section import with a dynamic fragment. Find the template that includes your popout cart and replace the {% section popout-cart %} with <div data-em-async="/pages/popout-cart" />
Before:
templates/theme.liquid
1
...
2
3
<div id="nav-container">
4
{% section 'popout-cart' %}
5
</div>
6
7
...
Copied!
After:
templates/theme.liquid
1
...
2
3
<div id="nav-container">
4
<span data-em-async="/pages/popout-cart" />
5
</div>
6
7
...
Copied!
Its worth noting that this will only work when requests go through Edgemesh Server. To make sure design mode and page previews render as well, add a conditional to enable the dynamic fragment for the live site only.
templates/theme.liquid
1
...
2
3
<div id="nav-container">
4
{% if request.design_mode or content_for_header contains "previewBarInjector.init();" %}
5
{% section 'popout-cart' %}
6
{% else %}
7
<span data-em-async="/pages/popout-cart" />
8
{% endif %}
9
</div>
10
11
...
Copied!
You can use any HTML element you like with data-em-async but span or another inline element is probably best to prevent layout issues.
Last modified 18d ago
Copy link