In root.tsx
TSXapp/root.tsx
import {
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";
import type { LinksFunction } from "@remix-run/node";
export const links: LinksFunction = () => [
{
rel: "stylesheet",
href: "https://cdn.glopzi.com/YOUR_API_KEY.css",
},
];
export default function App() {
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<script
src="https://cdn.glopzi.com/modules/glopzi.js"
data-glopzi-key="YOUR_API_KEY"
async
/>
</body>
</html>
);
}The links() export
Remix uses the links() export to declare stylesheets that Remix renders inside the <Links /> component. Adding Glopzi’s stylesheet there ensures it lands in the head before first paint, just like a static <link> would.
You can return more entries from links() (your own stylesheets, fonts, etc.); the Glopzi entry is just one item in the array.
Common pitfalls
- Adding the script via
scripts()export: doesn’t work the same way; the export is for module scripts. A plain script tag in the body ofroot.tsxis the right approach. - Per-route scripts: don’t add Glopzi to a specific route’s component. The tag in
root.tsxcovers every page automatically; per-route would mean multiple instances initializing. - SPA navigation: Remix’s client-side navigation doesn’t reload the page, but Glopzi listens for navigation events and re-initializes animations on the new route. New page targets work without manual intervention.
Next steps
- Next.js and SvelteKit: the same pattern in different frameworks.
- Quickstart: any website: the generic walkthrough.
- Performance and Core Web Vitals: why the link tag matters for SSR.