Loading repository data…
Loading repository data…
aatuh / repository
Composable Next.js/TypeScript SaaS core: Clerk auth, i18n + SEO, cookie-consent–gated analytics, UI/layouts, markdown pages, HTTP client.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
A modular TypeScript core for building Next.js apps fast.
This repo is a pnpm workspace monorepo containing reusable packages for:
This is not a full application template. It’s a set of core packages you plug into your Next.js app.
Workspace root:
pnpm-workspace.yaml — workspace definition citeturn0search1turn0search5packages/* — the reusable packages (all currently private: true)Packages:
@api-boilerplate-core/analytics@api-boilerplate-core/analytics-plausible@api-boilerplate-core/analytics-umami@api-boilerplate-core/auth@api-boilerplate-core/auth-ui@api-boilerplate-core/auth-clerk@api-boilerplate-core/auth-setup@api-boilerplate-core/clerk@api-boilerplate-core/content@api-boilerplate-core/env@api-boilerplate-core/error-contracts@api-boilerplate-core/flags@api-boilerplate-core/http@api-boilerplate-core/i18n-shared@api-boilerplate-core/layouts@api-boilerplate-core/legal@api-boilerplate-core/seo@api-boilerplate-core/theme@api-boilerplate-core/ui@api-boilerplate-core/widgets"type": "module"pnpm install
pnpm lint
pnpm typecheck
Run scripts across all packages:
pnpm -r lint
Add this repo into your app monorepo and include its packages in your workspace globs.
Example pnpm-workspace.yaml:
packages:
- "apps/*"
- "packages/*"
- "vendor/api-boilerplate-core/packages/*"
Then in your app’s package.json:
{
"dependencies": {
"@api-boilerplate-core/ui": "workspace:*",
"@api-boilerplate-core/seo": "workspace:*"
}
}
The workspace: protocol forces pnpm to resolve to local workspace packages. citeturn0search9
#path: packagesThis repo also supports Git URL dependencies pointing to subpaths:
{
"dependencies": {
"@api-boilerplate-core/ui": "https://github.com/aatuh/api-boilerplate-core.git#path:/packages/ui",
"@api-boilerplate-core/seo": "https://github.com/aatuh/api-boilerplate-core.git#path:/packages/seo"
}
}
Pin to a tag/commit for reproducible installs.
Client-exposed env vars must be prefixed with NEXT_PUBLIC_.
NEXT_PUBLIC_ANALYTICS_ENABLED = "true" to enable analytics (globally)NEXT_PUBLIC_ANALYTICS_TRACK_LOCALHOST = "true" to allow tracking on localhostNEXT_PUBLIC_UMAMI_WEBSITE_IDNEXT_PUBLIC_UMAMI_HOST (optional URL)NEXT_PUBLIC_UMAMI_SCRIPT_URL (optional URL)NEXT_PUBLIC_CLERK_PUBLISHABLE_KEYNEXT_PUBLIC_CLERK_JWT_TEMPLATE (optional)NEXT_PUBLIC_SUPPORTED_LOCALES (CSV, e.g. "en,fi")NEXT_PUBLIC_DEFAULT_LOCALE (e.g. "en")NEXT_PUBLIC_LOCALE_AUTO_DETECT (true/false)NEXT_PUBLIC_APP_URL (canonical base URL)VERCEL_URL (auto-used if present)If you want other code to read consent state (e.g. analytics gates), you must wrap your app in CookieConsentProvider.
// app/providers.tsx
"use client";
import type { ReactNode } from "react";
import { CookieConsentProvider, CookieConsentBanner } from "@api-boilerplate-core/widgets";
import { DEFAULT_CONSENT_CONFIG } from "@api-boilerplate-core/legal";
export function Providers({ children }: { children: ReactNode }) {
return (
<CookieConsentProvider config={DEFAULT_CONSENT_CONFIG}>
{children}
<CookieConsentBanner />
</CookieConsentProvider>
);
}
Then in your root layout:
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
Note:
CookieConsentShellis a convenience component that renders the banner inside a provider, but it does not wrap your app’s children. Use it only if you don’t need consent state elsewhere.
UmamiAnalyticsGate only enables tracking when:
// app/providers.tsx
"use client";
import type { ReactNode } from "react";
import { CookieConsentProvider, CookieConsentBanner } from "@api-boilerplate-core/widgets";
import { DEFAULT_CONSENT_CONFIG } from "@api-boilerplate-core/legal";
import { AnalyticsListener } from "@api-boilerplate-core/analytics";
import { createAnalyticsEnv } from "@api-boilerplate-core/analytics/env";
import { UmamiAnalyticsGate } from "@api-boilerplate-core/analytics-umami/gate";
import { createUmamiEnv } from "@api-boilerplate-core/analytics-umami/env";
export function Providers({ children }: { children: ReactNode }) {
const analyticsEnv = createAnalyticsEnv();
const umamiEnv = createUmamiEnv();
return (
<CookieConsentProvider config={DEFAULT_CONSENT_CONFIG}>
<UmamiAnalyticsGate
enabled={analyticsEnv.enabled}
websiteId={umamiEnv.websiteId}
host={umamiEnv.host}
scriptUrl={umamiEnv.scriptUrl}
>
<AnalyticsListener />
{children}
</UmamiAnalyticsGate>
<CookieConsentBanner />
</CookieConsentProvider>
);
}
This repo includes a Clerk adapter package intended for Next.js middleware integration.
Clerk’s official middleware patterns evolve; follow Clerk’s docs for your Clerk/Next version and map it to @api-boilerplate-core/auth-clerk. citeturn0search0
@api-boilerplate-core/seo provides buildPageMetadata() and getSiteUrl() which help produce consistent canonical + hreflang + OpenGraph metadata.
import { buildPageMetadata } from "@api-boilerplate-core/seo";
export const metadata = buildPageMetadata({
title: "My page",
description: "My description",
path: "/pricing",
locale: "en",
index: true,
siteName: "MyApp",
});
"use client";.@api-boilerplate-core/env + Zod).pnpm install
pnpm lint
pnpm typecheck
pnpm -r lint
packages/<name>/package.json mirroring existing packages (type: module, exports, peerDependencies).src/index.ts with explicit exports.pnpm -r lintpnpm typecheckNEXT_PUBLIC_ env vars in client code.