sxg-rs is a set of tools for generating signed exchanges at serve time:
cloudflare_worker
runs on Cloudflare Workers.distributor
is an example implementation of privacy-preserving SXG prefetch of outlinks.fastly_compute
runs on Fastly Compute@Edge.http_server
runs as an HTTP reverse-proxy on Linux.playground
is a CLI for previewing LCP impact of SXG on any site.sxg_rs
is the Rust library that can be used as a basis for other serverless platforms.These tools enable sites to be prefetched from Google Search in order to improve their Largest Contentful Paint, one of the Core Web Vitals.
For other technology stacks, see this list of SXG tools.
After installing, take the following steps.
After installing, you may want to verify and monitor the results.
The worker contains some HTML processors. To activate them, explicitly label the character encoding as UTF-8, either via:
Content-Type: text/html;charset=utf-8
or via:
<meta charset=utf-8>
LCP can be further improved by instructing Google Search to prefetch render-critical subresources for the page.
Add a preload link tag to the page, such as:
<link rel=preload as=image href="https://github.com/google/sxg-rs/blob/main/foo.png">
sxg-rs will automatically convert these link tags into Link headers as needed for SXG
subresource
substitution.
This uses a form of subresource integrity that includes HTTP headers. sxg-rs
tries to ensure a static integrity value by stripping many noisy HTTP headers
(like Date) for signed subresources, but you may need to list additional ones
in the strip_response_headers
config param.
To confirm it is working, run:
$ go install github.com/WICG/webpackage/go/signedexchange/cmd/dump-signedexchange@latest
$ dump-signedexchange -uri "$HTML_URL" -payload=false | grep Link
and verify that there is a rel=allowed-alt-sxg
whose header-integrity
matches the output of:
$ dump-signedexchange -uri "$SUBRESOURCE_URL" -headerIntegrity
If you have any same-origin preload tags that should not be converted into
headers, add the data-sxg-no-header
attribute to them.
SXG preloading requires that the subresource is also an SXG. This worker assumes only same-origin resources are SXG, so its automatic logic is limited to those. You can manually support cross-origin subresources by adding the appropriate Link header as specified.
There are two syntaxes for behavior that happens only when the page is viewed as an SXG. If you write:
<script data-issxg-var>window.isSXG=false</script>
then its inner content will be replaced by window.isSXG=true
in an SXG. This
could be used as a custom dimension by which to slice web analytics, or as a
cue to fetch a fresh CSRF token.
If you write:
<template data-sxg-only>...</template>
then in an SXG, its inner content will be "unwrapped" out of the template and thus activated, and when non-SXG it will be deleted. Since SXGs can't Vary by Cookie, this could be used to add lazy-loaded personalization to the SXG, while not adding unnecesary bytes to the non-SXG. It could also be used to add SXG-only subresource preloads.
Optionally, preview the results in the browser:
Accept
header to
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
(equivalent to what Googlebot sends).