One script tag. A floating Summarize button on every page. Your URL, inside the answer.
AI engines don't rank links — they recommend trusted sources. Your readers already summarise your pages with an AI, and today that means copying something into a chat box. PageLens removes that step: they hover the button, pick an engine, and land in ChatGPT, Claude, Gemini, Grok, Copilot, Perplexity or Google AI Mode already asking about your page, with your prompt.
<script src="https://cdn.gracker.ai/summarize.min.js" defer></script>That's the whole install. Paste it before </body> and it works on every page of your site.
The pill variant, data-position="bottom-left". Hovering opens the engine menu.
- Why it matters · Free, and it stays free · Install
- Options · Button styles · Motion effects
- JavaScript API · How it works · Privacy
- Self-hosting · Develop · Deploy
- Caveats · Part of GrackerAI · Licence
40% of B2B buyers now use AI assistants to research solutions. AI engines don't rank links — they recommend trusted sources. If an AI can't find you, your customers won't either.
This is generative-engine and answer-engine optimisation (GEO/AEO), done from the one place you fully control: your own page.
| One tag, every page | Paste one script before </body> and the button appears across your site. |
| Your URL, inside the answer | Readers pick an engine and arrive already asking about your page, with your prompt. |
| Nothing loads until they click | No requests and no tracking while a reader is just reading. |
It does not rank your page or promise a citation. It removes the friction between your page and the answer engine, and puts your framing in the prompt instead of whatever the reader would have typed.
PageLens is not plan-gated. It is not metered, not seat-limited, and not tied to a GrackerAI subscription — use it on as many pages and as many sites as you like, forever, including after a GrackerAI plan ends.
Your monitoring stops when the plan does. Your AI visibility doesn't have to.
You do not need an account: the snippet above works on its own. GrackerAI customers also get a visual builder for the tag in the dashboard.
Default. Every option has a sensible default, so the bare tag is a complete install:
<script src="https://cdn.gracker.ai/summarize.min.js" defer></script>Configured. Every option is a data-* attribute on the same tag:
<script src="https://cdn.gracker.ai/summarize.min.js"
data-position="bottom-left"
data-providers="chatgpt,claude,aimode"
data-accent="#111111"
data-label="Ask AI"
defer></script>Only set what you want to change — anything you omit uses the default below.
| Attribute | Default | Notes |
|---|---|---|
data-position |
bottom-right |
top-left, top-center, top-right, middle-left, middle-right, bottom-left, bottom-center, bottom-right |
data-offset |
24px |
Distance from the screen edges, for preset positions |
data-x / data-y |
— | Custom position, any CSS length. Set both to override data-position |
data-providers |
all but Perplexity | Comma-separated, in menu order: chatgpt, claude, aioverview, aimode, gemini, grok, copilot, perplexity |
data-label |
Summarize |
Button text. Kept as the aria-label when circle hides it |
data-prompt |
see below | Sent to the engine. {url} and {title} are substituted |
data-accent |
#2563eb |
Button colour |
data-theme |
auto |
auto, light, dark |
data-variant |
pill |
Button style — see Button styles |
data-effect |
none |
Motion — see Motion effects. Stacks on any variant |
data-fx-colors |
accent + white | Comma-separated colours, spread evenly along the effect. Any count |
data-fx-width |
2px |
Thickness of the animated border band |
data-fx-speed |
per effect | One cycle, e.g. 1.4s. Omit to keep each effect's tuned default |
data-open-on |
hover |
hover or click. Click/tap and keyboard always work either way |
data-z-index |
2147483000 |
Stacking order of the widget's host element |
data-manual |
— | Present: skip auto-mount, call SummarizeThisPage.mount(opts) yourself |
Default prompt:
Summarize this page in a few short bullet points, then list any key numbers or dates:
{url}
Six ship in the box. All take data-accent and both themes.
data-variant |
|
|---|---|
pill |
Filled and rounded. The default. |
circle |
Icon-only FAB, 52px. Label becomes the aria-label. |
ghost |
Surface card, accent icon. |
glass |
Frosted — blurs the page behind it. |
square |
Softly rounded rectangle. |
text |
No chrome, just an underlined link. |
Five effects stack on top of any style via data-effect:
data-effect |
Default speed | |
|---|---|---|
trail |
Neon comet running the border | 3s |
radar |
Rotating beam with a tail | 2.2s |
glow |
Pulsing halo | 2.2s |
shimmer |
Highlight sweeping the edge | 2.6s |
ring |
Ring expanding outward, then gone | 1.9s |
Every effect takes as many colours as you give it, at whatever thickness and speed:
<script src="https://cdn.gracker.ai/summarize.min.js"
data-effect="trail"
data-fx-colors="#ff0055,#ffcc00,#00e5ff,#7c3aed"
data-fx-width="4px"
data-fx-speed="1.4s"
defer></script>Colours are spread evenly across the effect's stops — two give a clean neon comet, five give a
rainbow. glow derives its halo from the first two.
The animated rings are a masked ::before band, so they never cover the button's own background,
and everything stops under prefers-reduced-motion: reduce.
Add data-manual to skip auto-mount and drive it yourself. The global is SummarizeThisPage:
<script src="https://cdn.gracker.ai/summarize.min.js" data-manual defer></script>
<script>
const widget = SummarizeThisPage.mount({
position: 'bottom-left',
providers: 'chatgpt,claude',
accent: '#111111'
});
// later
widget.destroy();
</script>mount(opts) takes the same keys as the data-* attributes in camelCase (openOn, fxColors,
zIndex, …) and returns { el, destroy }.
Also exposed, for building your own UI on top:
defaults |
The DEFAULTS object above |
providers |
{ key: { name, icon, url(q) } } for all eight engines |
order, positions, variants, effects |
The valid values, in display order |
svg(key) |
The provider's icon as an <svg> string |
buttonIcon |
The button's own glyph |
providerUrl(key, url, title, prompt) |
The link a menu item would open |
css, accentRgb, fxStops, parseColors, positionStyle |
Internals the config UI reuses |
The widget appends a single host element to <body> and renders inside a shadow root, so your
site's CSS cannot reach into it and its CSS cannot leak out. Provider logos are inlined as SVG
paths, so it makes zero network requests of its own.
Menu links are built lazily — the href is set on hover/focus/click, from location.href and
document.title at that moment. Single-page apps therefore get the correct URL without re-mounting.
Auto-mount finds its own tag via document.currentScript, falling back to
script[src*="summarize"]. If you self-host under a different filename, keep summarize in it or
use data-manual.
- No backend, no analytics, no cookies, no storage.
- Nothing leaves the reader's browser until they click a provider — and then it is a normal navigation to that provider, carrying only the prompt and your URL.
- The widget fetches nothing at runtime; the only request is the one
<script>tag itself.
You do not have to load the widget from cdn.gracker.ai. Build it and serve it yourself:
npm install && npm run widget # -> public/summarize.min.js, ~7.7 KB gzippedTwo things to keep in mind when you do:
- Keep
summarizein the filename. Auto-mount finds its own tag viadocument.currentScript, falling back toscript[src*="summarize"]. Rename it to something else and the plain tag stops mounting — usedata-manualif you need a different name. - Serve it with a long cache TTL from a CDN or a custom domain, not from your app server.
Two URLs, depending on how much churn you want:
| URL | Gets |
|---|---|
https://cdn.gracker.ai/summarize.min.js |
The latest build, across major versions |
https://cdn.gracker.ai/summarize.v1.min.js |
The latest 1.x — fixes, never a breaking change |
<!-- pinned to 1.x -->
<script src="https://cdn.gracker.ai/summarize.v1.min.js" defer></script>Both are cached 5 minutes in the browser and 24 hours at the edge, so fixes reach your pages on their own within about a day. Neither is frozen — if you need a build that never changes under you, self-host a copy from a tagged release.
Breaking changes go to a new major (summarize.v2.min.js); v1 keeps working.
npm install
npm run dev # builds the widget, then serves the landing page + tag builder
npm test # widget unit checks (URL building, positioning, effect stops)
npm run build # widget + static site into ./dist| Path | |
|---|---|
widget/summarize.js |
Widget source. No dependencies, renders in a shadow root |
widget/test.mjs |
Unit checks, plain node — no test framework |
src/pages/index.astro |
Landing page and configure-to-copy tag builder |
src/styles/tokens.css |
Design tokens for the landing page |
public/configurator.js |
Builder logic — drives a live preview off the real widget |
public/summarize.min.js |
Build artifact, ~7.7 KB gzipped. Not committed — run npm run widget |
Site (static Astro build → assets-only Cloudflare Worker):
npm run deployWidget to R2:
R2_BUCKET=my-bucket npm run deploy:widgetServe the bucket through a custom domain so it gets a long cache TTL, then point the landing page's generated snippet at it:
PUBLIC_CDN_URL=https://cdn.gracker.ai/summarize.min.js npm run deployBreaking changes: version the object name (
summarize.v2.min.js) rather than overwriting. Embeds on other people's sites will cache the old one for a while.
- Engines differ. ChatGPT, Claude, Grok, Copilot, Perplexity and Google (AI Overview / AI Mode)
all take a query parameter. Gemini's
?q=is the least reliable of the set, which is why it is in the menu but easy to drop withdata-providers. - Prefill ≠ fetch. An engine accepting your prompt does not guarantee it will retrieve the URL.
- The page must be publicly reachable for an engine to read it. Staging and gated pages will not work.
GrackerAI helps B2B SaaS companies get discovered, cited, and recommended by AI search engines — ChatGPT, Perplexity, Claude, Gemini, Microsoft Copilot and Google AI Overviews.
| Monitor | Track how AI search engines mention your brand vs competitors, daily across all 6 engines |
| Analyze | Identify citation gaps where competitors appear and you don't |
| Optimize | Auto-generate authoritative content structured for AI citation |
| Scale | Build programmatic SEO portals that compound your AI visibility over time |
Platform results: 60% average visibility increase within 90 days, 3–5x higher conversion from AI traffic than traditional search, first results in 4–6 weeks.
PageLens is the free, no-account entry point — the part that works from inside your own pages. Everything in the table above is the paid platform; PageLens is not part of it and never expires.
Where the platform monitors those 6 engines, PageLens sends readers to all six plus Grok and Google AI Mode — eight destinations in the menu.
gracker.ai · Documentation · Free AI Visibility Audit · Book a demo · Blog
| Repository | |
|---|---|
| cyber-pulse | AI-powered news monitoring and content intelligence engine |
| GrackerAI-PageLens | This repo — the Summarize widget |
Not licensed for reuse yet — the source is public to read, but no open-source licence has been chosen, so default copyright applies. A licence will be added before this is meant to be forked or embedded from someone else's build.
Provider logos are SVG paths from lobehub/lobe-icons (MIT) — see THIRD-PARTY.md. The marks are trademarks of their owners and are used here only to label the link that opens each service; no affiliation or endorsement is implied.
Built by GrackerAI — generative-engine optimisation for B2B SaaS. San Francisco, CA · Partnered with Nvidia, Microsoft, Cloudflare and AWS.
