How-to guides
Accessibility and page weight: the strife-insights element
Turn on Studio's accessibility audit and page-weight check with the strife-insights element: the results in the live preview for every editor, and in Insights and the content list on teams with Content Insights. Where to place it in Astro, Next.js, Vue and Nuxt, .NET and plain HTML, and troubleshooting.
The <strife-insights> element lets Studio check your site's pages: an accessibility audit, and what each page weighs. The checks run while an editor has a page open in Studio's live preview, and the results go to two places:
- The live preview, for every editor: the preview's toolbar shows them while the editor works.
- Insights and the content list, on teams with Content Insights: Studio stores the results, so the accessibility audit shows in Insights, and both checks can be filtered on in the content list.
Your site turns both checks on with the one element, placed once in your layout's body:
<strife-insights hidden></strife-insights>The element renders nothing and needs no script of its own. Leave it out and neither check runs, so Insights gets no accessibility data either.
How it works
- The checks run in your page, and only in the preview. The preview SDK (
@strifeapp/strife) defines the element only when the page is framed, as it is in Studio's preview, so your visitors get an empty tag. It runs the accessibility audit with axe-core, which it downloads only when Studio asks for an audit, so visitors never load it. It weighs the page's images and embeds from the browser's own measurements. - Only Studio's new interface shows them. It asks for the audit when it connects to the page. The legacy interface never asks, and shows neither check.
- Only on the page the editor opened. If your site's client-side router swaps in another page inside the preview, the checks don't run there: that page's result would be shown, and stored, as the page being edited.
- The page sends nothing anywhere itself. It hands the results to Studio. On teams with Content Insights, Studio stores them per page and language, for Insights and the content list's Accessibility and Performance filters. The data comes from editing, not from your visitors.
Requirements
@strifeapp/strife1.23.0 or later on the page. A site that loads it from a CDN without a version, such ashttps://unpkg.com/@strifeapp/strife, already runs the latest. With npm, update it:npm install @strifeapp/strife@latest.- On Astro,
@strifeapp/astro1.10.0 or later. See the Astro tab below. - Studio's new interface for the editor.
- Content Insights on the team, to store the results. Without it, editors still see them in the preview.
Add the element
Put the element in the layout every page uses, inside <body>. Never put it in <head>: the browser ends the head at an element it doesn't know and moves everything after it into the body. hidden keeps the empty element out of your layout (in a grid or flex body it would take a track and a gap); the SDK still finds it. A layout rendered on the client, or inside a shadow root, works too: the checks start when the element connects.
---
import LivePreview from '@strifeapp/astro/LivePreview.astro';
---
<html lang="en">
<head>
<meta charset="utf-8" />
<LivePreview />
</head>
<body>
<slot />
<strife-insights hidden></strife-insights>
</body>
</html><LivePreview /> loads the preview SDK only in Studio's preview. Use @strifeapp/astro 1.10.0 or later, and if your package.json lists @strifeapp/strife as well, raise it to 1.23.0 or later too. If the layout has <Insights />, remove it (see Coming from the Insights component).
import type { ReactNode } from 'react';
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>
{children}
<strife-insights hidden></strife-insights>
</body>
</html>
);
}Load the preview SDK as in the Next.js tutorial. It loads the SDK on every page, so read Security below.
TypeScript doesn't know the tag and reports Property 'strife-insights' does not exist on type 'JSX.IntrinsicElements'. Declare it once, in a file your tsconfig.json includes:
import type { DetailedHTMLProps, HTMLAttributes } from 'react';
declare module 'react' {
namespace JSX {
interface IntrinsicElements {
'strife-insights': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
}
}
}Keep the import line: without it, the file replaces React's types instead of adding to them. This works with the types for React 18 and 19. In JavaScript you need none of it.
Put the element in the component every page renders in, such as app.vue in Nuxt or App.vue in Vue:
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<strife-insights hidden></strife-insights>
</template>Vue first tries to resolve the tag as a component and warns Failed to resolve component: strife-insights. Tell its compiler that the tag is a custom element:
export default defineNuxtConfig({
vue: {
compilerOptions: {
isCustomElement: (tag) => tag.startsWith('strife-'),
},
},
});With Vue and Vite, the same option goes to the Vue plugin in vite.config.ts: vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('strife-') } } }).
<body>
@RenderBody()
<strife-insights hidden></strife-insights>
</body>The layout loads the preview SDK as in Setup Real time preview in the .NET tutorial.
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module" src="https://unpkg.com/@strifeapp/strife"></script>
</head>
<body>
…
<strife-insights hidden></strife-insights>
</body>
</html>An address without a version always loads the latest SDK.
In any other framework the element is plain HTML. If its compiler rejects elements it doesn't know, tell it that strife-insights is a custom element: in Angular, add CUSTOM_ELEMENTS_SCHEMA to the component's schemas.
Coming from the Insights component
In @strifeapp/astro 1.9, <Insights /> in the head ran the accessibility audit. From 1.10.0 it renders nothing, and the SDK runs the audit itself from 1.23.0. An Astro site that still has <Insights /> from @strifeapp/astro 1.9.0 or earlier gets neither check once it picks up @strifeapp/strife 1.23.0. Update @strifeapp/astro to 1.10.0 or later, remove <Insights /> and add the element.
Security
The element is not a security boundary: the SDK runs the checks for whatever page frames it and asks, and the audit's result includes short HTML excerpts of the page. If your site loads the SDK for every visitor and renders anything visitor-specific, load it only on preview requests (as <LivePreview /> does on Astro), or limit who may frame your pages with Content-Security-Policy: frame-ancestors.
What editors see
- Accessibility: a button in the preview's toolbar with the number of failing rules. It lists every rule by impact, with the failing elements: hovering one outlines it in the preview, and clicking one opens the field it renders. The audit runs once the page has connected, 1.5 s after the editor's last edit, and on the rerun button.
- Page weight: the page's level (Poor, Needs improvement or Great) in its own tool, with the findings split into Your content and Template and code. Only content findings set the level.
- Stored results, on teams with Content Insights: the accessibility audit in Insights, and both checks as the content list's Accessibility and Performance filters. A page edited since its last check shows as unchecked until it is opened in the preview again.
Live preview has the details of both checks: how a finding is tied to a field, what the page-weight check measures and where the sizes come from.
Troubleshooting
- No accessibility or page-weight button in the preview:
- Check that
<strife-insights>is in the<body>of the page in the preview frame. Your browser's developer tools show the frame's elements. - Check the SDK's version:
npm ls @strifeapp/strifelists the installed versions, and the page needs 1.23.0 or later. - On Astro, check that
@strifeapp/astrois 1.10.0 or later. - Check that the editor uses Studio's new interface.
- Check that
- Vue or Nuxt warns
Failed to resolve component: strife-insights: setisCustomElementas in the Vue and Nuxt tab. - TypeScript reports
Property 'strife-insights' does not exist on type 'JSX.IntrinsicElements': add the declaration from the Next.js tab. - The results show in the preview, but not in Insights or the content list's filters: the team doesn't have Content Insights.
- Insights says "No accessibility data yet for this page": the page hasn't been checked yet. Open it in the live preview once, after the element is in place.
- Image sizes marked ≈: the image comes from another origin without a
Timing-Allow-Originheader, so its size is estimated. See Performance in the preview.