Server Side Rendering — Akamai Setup Instructions

Modified on Thu, 8 Oct at 9:59 PM

Use this guide if you want server-side rendering (SSR) of Schema App’s structured data (JSON-LD) for crawlers and bots, you use Akamai as your CDN provider, and your account has Edge Workers available. The instructions below explain how to install the Schema App CDN injection Edge Worker into your existing Akamai property. The worker injects JSON-LD markup from Schema App’s CDN into the <head> of HTML pages when the request is from a bot or crawler. Normal user traffic is unchanged.



Note: Currently, Akamai Server Side Rendering is only available to Enterprise (Highlighter) clients.



Prerequisites

  • An Akamai account with Property Manager and Edge Workers enabled.
  • Your existing property (the one that serves your website).
  • Your Schema App account ID (e.g. ExampleAccount, ExampleAccount/Test). Get this from the Schema App home page if you don’t have it.
Note: Be sure to not include the http://schemaapp.com/db/



Overview

You will:

  1. Deploy the Edge Worker bundle and note its ID.
  2. Add the user-defined variables to your property.
  3. Add a Conditional Origin rule so the worker’s CDN subrequests go to Schema App’s CDN.
  4. Add a Schema App Inject rule that runs the Edge Worker only for bot User-Agents.
  5. Configure cache key and bypass so the worker and subrequests behave correctly.
  6. Activate to staging, test, then activate to production.

Rule order matters: The Conditional Origin rule must be evaluated before the Schema App Inject rule (e.g. place it higher in the default rule tree)


Step-by-step setup

1. Deploy the Edge Worker

  1. Download the bundle from Schema App’s CDN:

  2. Upload the bundle in Akamai:

    • Control Center: Edge Workers → Create / Manage → upload the downloaded .tgz and create a new Edge Worker (or new version of an existing one).
    • CLI: Use the Akamai Edge Workers CLI to upload the bundle.
  3. Note the Edge Worker ID (e.g. 105498). You will use it when adding the Edge Worker behavior.





2. Add user-defined variables

In Property Manager, open your property and add user-defined variables (e.g. under the Variables section or in the default rule’s configuration). Use one of the two options below.


Option A: Single hostname / single Schema App account

Add these two variables:

Variable nameValueNotes
PMUSER_SCHEMAAPP_ACCOUNT_IDYour Schema App account ID (e.g. ExampleAccount)Exact name — no leading or trailing spaces.
PMUSER_SCHEMAAPP_CDN_BASE_URLhttps://<your-property-hostname>Same scheme + host as the request (e.g. https://www.yourdomain.com). No path, no trailing slash.Do not set this to https://data.schemaapp.com — the worker will ignore it and skip CDN subrequests.


Option B: Multiple hostnames or Schema App accounts

Use this when one Akamai property serves more than one hostname, or more than one Schema App project on the same hostname (split by URL path). Requires Edge Worker bundle version 1.5 or later; re-download the bundle (step 1) if yours is older.

Add this one variable:

Variable nameValueNotes
PMUSER_SCHEMAAPP_PROJECTSA JSON array of projects (see example below)Exact name — no leading or trailing spaces.

Example:

[
  {"baseUrl":"https://en.example.com","accountId":"ExampleEN"},
  {"baseUrl":"https://fr.example.com","accountId":"ExampleFR"},
  {"baseUrl":"https://www.example.com","pathPrefix":"/en","accountId":"ExampleWebEN"},
  {"baseUrl":"https://www.example.com","pathPrefix":"/fr","accountId":"ExampleWebFR"}
]

Each entry has these fields:

FieldRequiredMeaning
baseUrlYesScheme + host (e.g. https://www.yourdomain.com). Must be a hostname on this property, not data.schemaapp.com.
accountIdYesSchema App account ID for that entry (same format as PMUSER_SCHEMAAPP_ACCOUNT_ID).
pathPrefixNoMatch this path and anything under it (/en matches /en and /en/about). Omit to match any path on that host.

Matching: hostname first (case-insensitive and exact, so list both www and the bare domain if both are used), then the longest matching pathPrefix. A request that matches no entry is served unchanged, with no markup.

If PMUSER_SCHEMAAPP_PROJECTS is set, the Option A variables are ignored. A one-entry list is the same as Option A.

To confirm each hostname and path maps to the right account, see How-To: Troubleshoot Akamai Integration.


Optional: Debug mode

Works with either option. Add this variable only while troubleshooting:

Variable nameValueNotes
PMUSER_SCHEMAAPP_DEBUGtrueTurns on diagnostic output. Remove when done. See How-To: Troubleshoot Akamai Integration.


Important:

  • Variable names must match exactly (no extra spaces before or after).
  • Each CDN base (PMUSER_SCHEMAAPP_CDN_BASE_URL, or each baseUrl in PMUSER_SCHEMAAPP_PROJECTS) must be a hostname on this property. The worker sends subrequests to that host; your Conditional Origin rule then forwards those requests to Schema App’s CDN.
Note: Be sure to not include the http://schemaapp.com/db/ part of the Account ID. For example, http://schemaapp.com/db/SchemaApp must be shortened to just SchemaApp.




3. Add the Conditional Origin rule (CDN proxy)

This rule sends the worker’s CDN subrequests to Schema App’s CDN. It must be a top-level rule (sibling of your other rules), and it should be placed above the Schema App Inject rule so it is evaluated first.

  1. Create a new rule (e.g. name: Conditional Origin Definition).

  2. Criteria:

    • Request Header → Header name:X-SchemaApp-CDN-Request
    • Match:Exists (or value true).
      No path or other conditions.
  3. Behaviors:

    • Origin (or Origin Server / Conditional Origin):
      • Origin hostname:data.schemaapp.com
      • Origin type: HTTPS (port 443).
      • Forward host header:Origin hostname (so CloudFront receives Host: data.schemaapp.com). This is required; if you forward the request host instead, CloudFront may return 503.
      • Save the origin.
    • Optionally add CP code if your property uses it.
  4. Path: Forward the path as-is. Do not strip or rewrite the path. The worker sends paths like /{accountId}/{base64PageUrl} that the Schema App CDN expects.

  5. Do not cache responses from this rule — add a Caching behavior to this rule and set it to NO_STORE (or Do not store). Responses from the Schema App CDN must not be cached by Akamai; caching of markup is managed on the Schema App side. If you omit this, a parent rule may cache these responses and bots could receive stale or incorrect JSON-LD.


Note: This section is the most likely to require troubleshooting. Your CSM may request a copy of the integration code to share with our Engineering team to review.

4. Add the Schema App Inject rule (Edge Worker)

  1. Create a new rule (e.g. name: Schema App Inject).

  2. Select 'Match All'. Only requests that match all the criteria will invoke the worker.

  3. Criteria: Match → User-Agent → is one of (or Matches regex), with a list of bot identifiers.

    • For example: *SchemaBot*, *Googlebot*, *Bingbot*, *Slurp*. Make sure to add wildcards around each botname so it will match against the useragent string.
    • Schema App maintains a recommend list of Bots here. Add or remove bots per your requirements, but ensure that *SchemaBot* is included in this list to allow Schema App's crawler to evaluate the markup.

  4. Criteria: Match → Request Method → is → GET. Only requests to pages that should display Schema Markup will invoke the worker.

  5. Behaviors:

    • Edge Worker: Enable, and select the Edge Worker you uploaded (by the ID you noted earlier).
    • Set Continue on error as desired (typically false).

5. Cache key and subrequest bypass

The worker fetches the page HTML from the same URL the client requested. To avoid cache collisions and infinite loops:

  1. Cache key: Add the X-Subrequest header to the cache key for the behavior (or rule) that serves the Edge Worker. That way the worker’s internal “origin fetch” (which sends X-Subrequest: true) is cached separately from the response the client receives (the modified HTML).

  2. Bypass the worker on subrequests: Add a condition (or rule) so that when the request has the header X-Subrequest = true, the Edge Worker is not invoked. The worker itself adds this header only to its own origin fetch; normal clients do not send it. This prevents the origin subrequest from re-triggering the worker.

(Exact placement of cache key and bypass depends on your property structure; ensure the origin fetch uses a distinct cache key and does not run the worker again.)


6. Save, activate, and test

  1. Save the property version.

  2. Activate to Staging. In Property Manager, use Activate → Activate to Staging (or equivalent) for this version.

  3. Test on staging:

    • Send a request with a bot User-Agent to a page that returns HTML, e.g.:
      curl -s -A "Mozilla/5.0 (compatible; SchemaBot/1.2; +https://www.schemaapp.com/bot/)" \
        "https://<your-staging-hostname>/<path>" -o response.html
      
    • Open response.html and confirm you see <script type="application/ld+json" data-source="SchemaApp-Akamai:..."> in the <head> (if the Schema App CDN has data for that URL).
    • In Akamai logs or Test Center, confirm the worker runs and that subrequests to the CDN return 200 (not 503).
    • If markup is missing or subrequests fail, see How-To: Troubleshoot Akamai Integration.
  4. Activate to Production when staging looks correct.


Quick reference

WhatValue or action
CDN origin hostnamedata.schemaapp.com
Forward host header (for CDN origin)Origin hostname (required)
Conditional Origin matchRequest header X-SchemaApp-CDN-Request exists
Conditional Origin cachingNO_STORE — do not cache CDN responses on this rule
PMUSER_SCHEMAAPP_CDN_BASE_URLSingle project: https://<your-property-hostname> (same as request host; not data.schemaapp.com)
PMUSER_SCHEMAAPP_ACCOUNT_IDSingle project: your Schema App account ID; variable name with no trailing space
PMUSER_SCHEMAAPP_PROJECTSMultiple hostnames or path-split accounts: JSON array of {baseUrl, accountId, pathPrefix}. Replaces the two variables above when set.
PMUSER_SCHEMAAPP_DEBUG(Optional) true while troubleshooting
Cache keyInclude X-Subrequest so origin fetch is cached separately
Bypass worker whenRequest header X-Subrequest is present

Troubleshooting

For debug mode, status messages, and fixes for common issues, see How-To: Troubleshoot Akamai Integration.



Data Flow Diagrams


For bots you can see the flow that is taken



For normal web users (humans) the flow is much simpler as it skips injecting markup



In terms of accessing the CDN the functionality is shown below




Frequently Asked Questions


How many milliseconds does the Edge Worker add to the Time to First Byte (TTFB)?


The worker only fires for bot User-Agents (a Property Manager condition), so real users have zero TTFB impact by design.

For bots, the three sub-requests — origin HTML, Schema App main JSON-LD, and the highlighter — are dispatched in parallel via Promise.allSettled. TTFB is therefore bounded by the slowest of the three, not their sum:

ScenarioAdded latency
CDN edge-cached (typical after first crawl)
2–10 ms
CDN slightly slower than origin
15–40 ms
CDN cold cache miss
50–150 ms

The HtmlRewritingStream is a streaming transformer, not a buffer, so it adds only ~1–5 ms regardless of page size.


In total for bots the typical is ~50ms. 


If the Schema App API or the Edge Worker fails, does the page still render the core content, or is there a risk of breaking the source code?


The worker is well-hardened. Every CDN failure path falls back to serving the origin HTML untouched if the worker fails your page is rendered as if the worker didn't execute. 

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article