This page is written for both humans and coding agents (Claude Code, Cursor, Copilot, Windsurf, v0, Lovable, Bolt…). Share this URL with your agent and ask it to add the background.
- Markdown version: https://www.shaderz.fun/docs.md
- LLM index: https://www.shaderz.fun/llms.txt
- Runtime script: https://www.shaderz.fun/shaderz.js
- Visual editor: https://www.shaderz.fun/editor
Using Shaderz is free for personal and commercial projects. No attribution required.
Quick start for coding agents
Follow these steps exactly.
- Load the runtime once per page, ideally just before
</body>or in<head>withdefer:
<script src="https://www.shaderz.fun/shaderz.js" defer></script>
- Add a
data-shaderzattribute to the element that should get the animated background. The element keeps its content. The script inserts a<canvas>behind the content of that element, sized to it.
<section data-shaderz="s=aurora&c1=22c55e&c2=06b6d4&c3=a855f7&bg=020617" style="min-height: 80vh">
<h1>Your headline</h1>
</section>
- Pick the config. The value of
data-shaderzis a query string of parameters (see the parameters table). If the user gave you a Shaderz link, take the config from it (see "From a Shaderz link"). If not, pick one of the ready-made configs below or compose one from the brand colors.
That is the whole integration. Do not install anything else.
Rules for agents
- Do not copy shader code into the project. Use the script.
- Keep text readable: if text sits on top of the background, check contrast. Add an overlay such as
background: linear-gradient(rgba(0,0,0,.35), rgba(0,0,0,.35))on a child element if needed. - Use
data-shaderzon a dedicated empty element when the framework re-renders the container's children (React, Vue, Svelte). See the framework sections. - Colors: write them as
rrggbbwithout#in the attribute (c1=ff7a18).%23ff7a18and#ff7a18also work. - Only parameters that differ from the defaults need to be present.
- The script respects
prefers-reduced-motion: it renders a still frame for those users. Keep that behavior unless the user explicitly asks otherwise.
From a Shaderz link
Users usually design their background in the editor and send you a link.
- Editor link like
https://www.shaderz.fun/editor?s=mesh&c1=ff6ec7: everything after?is the config. Use it as is:data-shaderz="s=mesh&c1=ff6ec7". - Gallery link like
https://www.shaderz.fun/p/abc123xy: fetchhttps://www.shaderz.fun/api/presets/abc123xy. The JSON response has aconfigfield (the query string) and a ready-to-pastesnippet. - Embed link like
https://www.shaderz.fun/embed?s=aurora: same as the editor link, the query string is the config.
Example response of the preset API:
{
"slug": "abc123xy",
"name": "Midnight aurora",
"config": "s=aurora&c1=22c55e&c2=06b6d4&c3=a855f7&bg=020617",
"params": { "shader": "aurora", "c1": "#22c55e", "…": "…" },
"snippet": "<div data-shaderz=\"s=aurora&c1=22c55e&c2=06b6d4&c3=a855f7&bg=020617\"></div>\n<script src=\"https://www.shaderz.fun/shaderz.js\" defer></script>"
}
Preset library
If the user describes a mood instead of giving a link ("calm ocean", "neon cyberpunk", "warm and cozy"), pick a preset from the library instead of inventing values:
- Fetch
https://www.shaderz.fun/presets.json. It contains 1000 presets:{ id, name, shader, tags, config }. - Choose the preset whose
nameandtagsbest match the request. Tags cover moods (calm, energetic, dark, light), themes (ocean, space, coffee, saas…), colors and shader families. - Use its
configas the value ofdata-shaderz. To use brand colors, replacec1,c2,c3(andbg) in the config with the brand hex values.
{ "id": "northern-lights-aurora", "name": "Northern Lights Aurora", "shader": "aurora",
"tags": ["aurora", "northern lights", "night", "green", "purple", "sky", "dark", "calm"],
"config": "s=aurora&c1=22c55e&c2=06b6d4&c3=a855f7&bg=020617&…" }
Framework recipes
Plain HTML, WordPress, Webflow, Framer, Shopify
Paste the script in the site's custom code (footer or head) and add the attribute on the section. In page builders that cannot add attributes, use an HTML embed block with an absolutely positioned div:
<div data-shaderz="s=aurora&c1=22c55e&c2=06b6d4&c3=a855f7&bg=020617" aria-hidden="true"
style="position:absolute;inset:0;z-index:0"></div>
Full-page background
<div data-shaderz="s=aurora&c1=22c55e&c2=06b6d4&c3=a855f7&bg=020617" aria-hidden="true"
style="position:fixed;inset:0;z-index:-1"></div>
<script src="https://www.shaderz.fun/shaderz.js" defer></script>
Next.js (App Router)
Load the script once in the root layout with next/script, then use the attribute on an empty, absolutely positioned div inside a relative section. Works with client-side navigation: the script watches the DOM and mounts new elements automatically.
// app/layout.tsx
import Script from "next/script";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script src="https://www.shaderz.fun/shaderz.js" strategy="afterInteractive" />
</body>
</html>
);
}
// any server or client component
export function Hero() {
return (
<section className="relative isolate min-h-[80vh] overflow-hidden">
<div
data-shaderz="s=aurora&c1=22c55e&c2=06b6d4&c3=a855f7&bg=020617"
aria-hidden
className="absolute inset-0 -z-10"
/>
<h1 className="relative">Your headline</h1>
</section>
);
}
Use strategy="afterInteractive" (not beforeInteractive) so the canvas is added after hydration.
React (Vite, CRA, Remix)
Add <script src="https://www.shaderz.fun/shaderz.js" defer></script> to index.html (or the root document), then use the same empty div pattern as in Next.js. Changing the data-shaderz value from React updates the background live.
For programmatic control:
import { useEffect, useRef } from "react";
declare global {
interface Window {
Shaderz?: {
mount: (el: Element, config?: string | Record<string, unknown>, opts?: { motion?: "auto" | "always"; dpr?: number; paused?: boolean }) => {
set: (patch: string | Record<string, unknown>) => void;
replace: (config: string | Record<string, unknown>) => void;
pause: () => void;
play: () => void;
destroy: () => void;
};
};
}
}
export function ShaderzBackground({ config }: { config: string }) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!ref.current || !window.Shaderz) return;
const inst = window.Shaderz.mount(ref.current, config);
return () => inst.destroy();
}, [config]);
return <div ref={ref} aria-hidden style={{ position: "absolute", inset: 0, zIndex: -1 }} />;
}
Vue, Nuxt, Svelte, SvelteKit, Astro, Angular
Load the script once in the app shell, then bind the attribute on an empty element:
<!-- Vue -->
<div :data-shaderz="config" aria-hidden="true" class="absolute inset-0 -z-10"></div>
<!-- Svelte -->
<div data-shaderz={config} aria-hidden="true" class="absolute inset-0 -z-10"></div>
<!-- Astro -->
<div data-shaderz="s=aurora&c1=22c55e&c2=06b6d4&c3=a855f7&bg=020617" aria-hidden="true" class="absolute inset-0 -z-10"></div>
<script is:inline src="https://www.shaderz.fun/shaderz.js" defer></script>
Self-hosting
The script has no dependencies and talks to no server after loading. To remove the dependency on www.shaderz.fun, download it into the project and serve it yourself:
curl -o public/shaderz.js https://www.shaderz.fun/shaderz.js
Then use <script src="/shaderz.js" defer></script>.
iframe (no script)
If scripts are not allowed, embed the background as an iframe:
<iframe src="https://www.shaderz.fun/embed?s=aurora&c1=22c55e&c2=06b6d4&c3=a855f7&bg=020617" title="" aria-hidden="true" tabindex="-1"
style="position:absolute;inset:0;width:100%;height:100%;border:0;z-index:-1;pointer-events:none"></iframe>
Parameters
All parameters are optional. Short keys and long names are both accepted.
| Key | Long name | Type | Default | Values | Description |
|---|---|---|---|---|---|
s |
shader |
enum | gradient |
gradient, mesh, aurora, liquid, blobs |
Shader family. See the shader families section. |
sh |
shape |
enum | plane |
plane, sphere, water |
Surface shape. Only used when shader is gradient. |
c1 |
c1 |
hex color | #ff7a18 |
#rrggbb or rrggbb |
First color. |
c2 |
c2 |
hex color | #af002d |
#rrggbb or rrggbb |
Second color. |
c3 |
c3 |
hex color | #319197 |
#rrggbb or rrggbb |
Third color. |
bg |
bg |
hex color | #000000 |
#rrggbb or rrggbb |
Background color. Also the 4th color of mesh, the sky of aurora, the base of blobs and liquid. |
sp |
speed |
number | 0.4 |
0 to 2 | Animation speed. 0 freezes the animation. |
st |
strength |
number | 1.2 |
0 to 3 | Displacement or warp amount. |
dn |
density |
number | 1.1 |
0.1 to 4 | Detail scale. Higher means smaller features. |
fq |
frequency |
number | 5.5 |
0 to 10 | Secondary noise and motion frequency. |
gr |
grain |
number | 0.15 |
0 to 1 | Film grain amount. |
br |
brightness |
number | 1.1 |
0.2 to 2 | Overall brightness multiplier. |
lt |
light |
enum | 3d |
3d, flat |
Lighting model. Only used when shader is gradient. |
rf |
reflection |
number | 0.1 |
0 to 1 | Highlights and fresnel glow. |
wf |
wireframe |
boolean (1 / 0) |
false |
Editor-only preview flag. Ignored by the script. | |
cd |
cDist |
number | 7 |
1 to 20 | Camera distance. Only used when shader is gradient. |
cp |
cPolar |
number | 60 |
0 to 89 | Camera angle from above, in degrees. Only used when shader is gradient. |
ca |
cAzimuth |
number | 0 |
-180 to 180 | Camera rotation around the vertical axis, in degrees. Only used when shader is gradient. |
cz |
zoom |
number | 1 |
0.3 to 3 | Camera zoom. Only used when shader is gradient. |
Shader families
- gradient: a 3D surface displaced by noise, lit and viewed by a camera. Shapes:
plane(rolling hills seen at an angle),sphere(a morphing blob),water(waves). Uses the camera parameters. - mesh: flat mesh gradient with four soft color points (c1, c2, c3, bg) drifting around. Clean SaaS look.
- aurora: glowing horizontal ribbons over a dark sky. Use a dark
bg. - liquid: domain-warped fluid with metallic highlights. Good for chrome, marble, lava.
- blobs: soft metaballs floating on the background. Playful.
Ready-made configs
- Sunset (gradient, plane):
(defaults)· preview - Ocean (gradient, water):
sh=water&c1=0b3d91&c2=1fb6ff&c3=7df9ff&bg=020617&st=0.8&dn=1.6&cp=70· preview - Orb (gradient, sphere):
sh=sphere&c1=ffffff&c2=ffbb00&c3=0700ff&sp=0.1&st=1&cd=6&cp=75· preview - Candy (mesh):
s=mesh&c1=ff6ec7&c2=ffd166&c3=6ee7ff&bg=ffffff&st=1.5&gr=0.05· preview - Northern (aurora):
s=aurora&c1=22c55e&c2=06b6d4&c3=a855f7&bg=020617&dn=1.2· preview - Mercury (liquid):
s=liquid&c1=e5e7eb&c2=6b7280&c3=f9fafb&bg=111827&st=1.4&dn=1.3&gr=0.1· preview - Lava (blobs):
s=blobs&c1=f97316&c2=ef4444&c3=facc15&bg=1c0a00&dn=1.4· preview
Attributes
| Attribute | Effect |
|---|---|
data-shaderz |
Config (query string, full Shaderz URL, or JSON object). Changing it updates the background live. Removing it removes the background. |
data-shaderz-motion="always" |
Animate even when the user prefers reduced motion. Default is auto. |
data-shaderz-dpr="1" |
Max device pixel ratio. Default 2. Lower it on heavy pages. |
data-shaderz-paused |
Render a still frame. Remove the attribute to resume. |
JavaScript API
The script exposes window.Shaderz:
const bg = Shaderz.mount(document.querySelector("#hero"), "s=mesh&c1=ff6ec7", { motion: "auto", dpr: 2 });
bg.set({ c1: "#00ff99", speed: 0.8 }); // merge
bg.replace("s=aurora"); // reset to defaults + config
bg.pause(); bg.play();
bg.destroy();
Shaderz.parse("s=blobs&sp=1"); // -> full params object
Shaderz.refresh(); // rescan the DOM for [data-shaderz]
Behavior
- Renders with WebGL2 into a
<canvas>inserted as the first child of the element, withposition:absolute; inset:0; z-index:-1; pointer-events:noneandaria-hidden="true". The element getsisolation:isolate, andposition:relativeif it was static, so the canvas stays behind its content. - Pauses when the element is off screen or the tab is hidden.
- Respects
prefers-reduced-motionwith a still frame. - Without WebGL2, falls back to a static CSS gradient of c1, c2 and c3.
- Elements added later (SPA navigation, client rendering) are mounted automatically. Removed elements are cleaned up.
Troubleshooting
- Nothing shows: the element has no height. Give it a height or
min-height. - Canvas covers the content: a parent sets
overfloworz-indexin a way that breaks stacking. Put the attribute on an emptyposition:absolute; inset:0div inside the section. - Colors ignored: check the hex has 6 digits. Short hex like
fffis not supported. - Hydration warning in React: load the script after hydration (
next/scriptwithafterInteractive), and use an empty div.