No-JavaScript Fallback
The problem
@squircle-js/react relies on JavaScript to measure element dimensions and compute the SVG clip-path. When JavaScript is disabled or hasn't loaded yet, the element will have no clip-path applied, leaving it unstyled.
To handle this gracefully, the library ships SquircleNoScript.
How SquircleNoScript works
SquircleNoScript renders a <noscript> block containing a CSS rule:
[data-squircle] {clip-path: none !important;border-radius: attr(data-squircle) !important;}
Every Squircle component writes the cornerRadius value to a data-squircle attribute on its DOM node. When JavaScript is disabled, the browser applies the noscript CSS, which:
- Removes the (non-functional) clip-path
- Falls back to standard
border-radiususing the radius value stored indata-squircle
The result is a rounded element that looks correct even without JavaScript — not a perfect squircle, but a clean, rounded shape that matches the intended cornerRadius.
Setup
Add SquircleNoScript once at the top of your app, typically in your root layout. It only renders inside a <noscript> tag, so it has zero impact on JavaScript-enabled users.
import { SquircleNoScript } from "@squircle-js/react";export default function RootLayout({ children }) {return (<html><body><SquircleNoScript />{children}</body></html>);}
No other configuration is needed. All Squircle components on the page will automatically benefit from the fallback.
SSR considerations
During server-side rendering, the clip-path style is not yet computed (it requires measuring the element's size in the browser). This means there is a brief window on first paint where the element may appear without the squircle clip-path, particularly for elements where defaultWidth and defaultHeight are not provided.
To minimise this:
- Provide
defaultWidthanddefaultHeightwhen the element size is known, so the clip-path can be computed on the first render pass - Use
StaticSquirclefor elements with fixed dimensions — it computes the path synchronously and can render a stableclip-pathfrom the server
// Server-friendly: clip-path computable immediately<StaticSquirclewidth={48}height={48}cornerRadius={12}cornerSmoothing={0.6}className="bg-blue-500"/>// Also works: defaultWidth/defaultHeight give the component a starting point<SquircledefaultWidth={128}defaultHeight={128}cornerRadius={20}cornerSmoothing={0.6}className="bg-blue-500"/>
What users see
| Scenario | Visual result |
|---|---|
| JavaScript enabled | Full squircle clip-path |
JavaScript disabled, SquircleNoScript present | Rounded corners via border-radius |
JavaScript disabled, no SquircleNoScript | Square element (no rounding) |
SSR, before hydration, with defaultWidth/defaultHeight | Full squircle clip-path |
| SSR, before hydration, without defaults | No clip-path on first paint |