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:
<!-- simplified -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Store</title>
</head>
<body>
<div class="title">My Store</div>
<div class="welcome">Welcome {{ customer.name }}</div>
<ul>
<li><a href="/product-1"><img src="/product-1.png" /></a>
<li><a href="/product-2"><img src="/product-2.png" /></a>
<li><a href="/product-3"><img src="/product-3.png" /></a>
</ul>
</body>
</html>
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:
<div class="welcome">Welcome {{ customer.name }}</div>
Then we will update our main HTML with the Edgemesh Server Templating to fetch the dynamic content from the client-side.
<!-- simplified -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Store</title>
</head>
<body>
<div class="title">My Store</div>
<span data-em-async="/welcome" />
<ul>
<li><a href="/product-1"><img src="/product-1.png" /></a>
<li><a href="/product-2"><img src="/product-2.png" /></a>
<li><a href="/product-3"><img src="/product-3.png" /></a>
</ul>
</body>
</html>
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:
<!-- simplified -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Store</title>
</head>
<body>
<div class="title">My Store</div>
<div class="welcome">Welcome John Doe</div>
<ul>
<li><a href="/product-1"><img src="/product-1.png" /></a>
<li><a href="/product-2"><img src="/product-2.png" /></a>
<li><a href="/product-3"><img src="/product-3.png" /></a>
</ul>
</body>
</html>
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 common Shopify use case, 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
<div class="popout-cart-container">
{% if cart.item_count > 0 %}
<h1>Cart</h1>
<form action="/cart" method="post" novalidate class="cart">
{% for item in cart.items %}
{% endfor %}
<footer class="cart-footer">
<p class="cart-subtotal">
<span class="cart-subtotal-title">{{ 'cart.general.subtotal' | t }}</span>
<span class="cart-subtotal">{{ cart.total_price | money }}</span>
</p>
<div class="cart-actions">
<button type="submit" name="checkout" class="btn">{{ 'cart.general.checkout' | t }}</button>
<button type="submit" name="update" class="text-link txt--minor">{{ 'cart.general.update' | t }}</button>
</div>
</footer>
</form>
{% else %}
<div class="text-center">
<h1>{{ 'cart.general.title' | t }}</h1>
<p class="cart-empty-message">{{ 'cart.general.empty' | t }}</p>
<p class="cart-cookie-message">{{ 'cart.general.cookies_required' | t }}</p>
<p class="cart-continue-browsing">{{ 'cart.general.continue_browsing_html' | t }}</p>
</div>
{% endif %}
</div>

Create a template alternate

Next, create a template alternate for your cart fragment. Set the Create a new template for dropdown to index and the template type to liquid. Let's name the template alternate popout-cart.
Creating template alternate.
Now that the template alternate 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/index.popout-cart.liquid
{% layout none %}
{% render 'popout-cart' %}

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 <span data-em-async="/?view=popout-cart" />
Before:
templates/theme.liquid
...
<div id="nav-container">
{% section 'popout-cart' %}
</div>
...
After:
templates/theme.liquid
...
<div id="nav-container">
<span data-em-async="/?view=popout-cart" />
</div>
...
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
...
<div id="nav-container">
{% if request.design_mode or content_for_header contains "previewBarInjector.init();" %}
{% render 'popout-cart' %}
{% else %}
<span data-em-async="/?view=popout-cart" />
{% endif %}
</div>
...
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.

Shopify Apps

In this example we are going to take a look at how to identify content that requires dynamic fragments and create a fragment to support common Shopify Apps including: Klaviyo, Elevar and Stamped.io/Smile.io. The techniques found in this section will give you the tools necessary to integrate with any Shopify App implementing server side rendered, dynamic data.

Identifying Dynamic Content

A good place to start in identifying dynamic requirements on your site is to visit your store (direct to Shopify), log in and view the page source view-source:https://yoursite.com. Next do a find on the page for the email you used to log in to your store. Anywhere you see your email in the HTML is most likely a liquid variable that has been server side rendered and will need to be extracted into a dynamic fragment. Any liquid variables that are rendered into the HTML will need to be moved to the dynamic fragment in order to be populated correctly.

Creating Dynamic Fragment for App Requirements

Now that you have identified the dynamic content on your page that needs to be extracted into a dynamic fragment, let's go ahead and create the fragment. For this example we will be using a website running Klaviyo.
First, create a new snippet that will contain all of our dynamic content. Call it dynamic-fragment.
Create a Snippet for Dynamic Content
You may already have some snippets for your App's initialization. If thats the case you can render them in our dynamic fragment snippet.
{% render 'elevar' %}
If not, you can either create a snippet per App to keep things a bit more organized, or you can just add the source directly to the dynamic fragment.
{% comment %}
Klaviyo
{% endcomment %}
<script>
var _learnq = _learnq || [];
_learnq.push(['identify', {
'$email' : '{{ customer.email }}',
}]);
</script>
You can combine all your dynamic app requirements into this one fragment in order to minimize requests to the backend of your site.
Next lets create an alternate template for the dynamic fragment. Create a new index page variant, set it to liquid and name it dynamic.
Create Alternate Template
Inside this template, we can set layout to none and render our new fragment snippet.
{% layout none %}
{% render 'dynamic-fragment' %}
Now back in our theme.liquid we can remove any code that was moved to the dynamic fragment snippet and render the dynamic fragment.
{% if request.design_mode or content_for_header contains "previewBarInjector.init();" %}
{% render 'dynamic-fragment' %}
{% else %}
<span data-em-async="/?view=dynamic" />
{% endif %}
Now your Apps will have the dynamic data that they need in order to function properly. If you add any new Apps that require server side rendered variables, be sure to add them to the dynamic-fragment snippet.