@keystone-sites/services
v1.0.2
Published
Keystone Sites Services - analytics/ads providers (Meta Pixel, PostHog, GTM) and the KeystoneServices injection shell for customer websites
Maintainers
Keywords
Readme
@keystone-sites/services
Analytics/ads providers and the injection shell for Keystone customer websites. Supplies Meta Pixel (browser + CAPI coordination), PostHog (events, pageviews, client log shipping via OTel), Google Tag Manager, and the KeystoneServices server component that wires them all up from server-fetched config.
KeystoneServices
KeystoneServices is a slim async server component that fetches getAdsConfig(), getAnalyticsConfig(), and getCompanyInformation() and hands tracker IDs to a client ConsentGatedTrackers gate. It does not call headers() or cookies() — those APIs in the root RSC tree break OpenNext on-demand ISR for CMS detail routes.
// app/layout.tsx
import { KeystoneServices } from '@keystone-sites/services';
import { CONSENT_REGIME_BOOTSTRAP_SCRIPT } from '@keystone-sites/core/consent';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<script dangerouslySetInnerHTML={{ __html: CONSENT_REGIME_BOOTSTRAP_SCRIPT }} />
</head>
<body>
<KeystoneServices>{children}</KeystoneServices>
</body>
</html>
);
}// middleware.ts
export { consentRegimeMiddleware as middleware } from '@keystone-sites/core/consent/middleware';Consent models (evaluated on the client from cookies / localStorage + the middleware regime cookie):
- CCPA/CPRA (default): trackers mount unless the visitor previously declined.
- GDPR (EU/EEA/UK/CH): nothing mounts until the visitor explicitly grants that category. Meta Pixel →
advertising; PostHog + GTM →analytics.
Every service is a silent no-op when its config is not provisioned.
Cookie consent
setPixelConsent / setAnalyticsConsent (in ./tracking) turn already-mounted trackers off/on live. First-time GDPR grants remount via the ks-consent-changed event that setStoredGranularChoice dispatches — no router.refresh() required.
Package exports
| Import path | Contents |
|---|---|
| @keystone-sites/services | KeystoneServices + everything from ./tracking |
| @keystone-sites/services/tracking | Meta Pixel, PostHog, GTM helpers + setPixelConsent / setAnalyticsConsent |
| @keystone-sites/services/services/KeystoneServices | The injection shell on its own |
Publishing workflow
Publish to the public npm registry in dependency order (wait for each package to propagate before publishing dependents):
# 1. @keystone-sites/core (no internal Keystone deps)
npm run test && npm publish --access public
# 2. @keystone-sites/services (depends on @keystone-sites/core)
npm run test && npm publish --access public
# 3. @keystone-sites/widgets (depends on @keystone-sites/core + @keystone-sites/services)
npm run test && npm publish --access public