
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
strapi-nextgen-framework
Advanced tools
Production-ready, type-safe framework bridging Strapi v4 CMS and Next.js 14+ App Router with automatic cache management, Error Boundaries, and SEO optimization
A high-performance, type-safe framework bridging Strapi CMS and Next.js with automatic cache management and dynamic rendering.
populate queriesnpm install strapi-nextgen-framework graphql graphql-request zod
npm install -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-graphql-request
Current Version: 0.1.0 (Release)
🎉 Production-Ready Release! All core features are implemented, documented, and ready for use:
💡 For a detailed step-by-step guide, see the Quick Start Tutorial in our documentation.
# .env.local
STRAPI_URL=http://localhost:1337/graphql
STRAPI_TOKEN=your_api_token_here
STRAPI_WEBHOOK_SECRET=your_webhook_secret
STRAPI_PREVIEW_SECRET=your_preview_secret
// lib/strapi.ts
import { createStrapiSDK } from 'strapi-nextgen-framework';
export const strapiClient = createStrapiSDK({
url: process.env.STRAPI_URL!,
token: process.env.STRAPI_TOKEN,
defaultLocale: 'en',
logging: {
queries: process.env.NODE_ENV === 'development',
cacheTags: process.env.NODE_ENV === 'development',
},
});
// app/[slug]/page.tsx
import { strapiClient } from '@/lib/strapi';
import { generateStrapiMetadata, StrapiRenderer } from 'strapi-nextgen-framework';
import { componentMap } from '@/components/strapi';
interface PageProps {
params: { slug: string };
}
// Generate metadata for SEO
export async function generateMetadata({ params }: PageProps) {
const page = await strapiClient.getPage(params.slug);
return generateStrapiMetadata(page.attributes.seo, {
metadataBase: new URL('https://example.com'),
});
}
// Render the page
export default async function Page({ params }: PageProps) {
const page = await strapiClient.getPage(params.slug);
return (
<main>
<StrapiRenderer
data={page.attributes.dynamicZone}
map={componentMap}
validation="warn"
/>
</main>
);
}
// components/strapi/index.tsx
import { z } from 'zod';
import { HeroSection } from './HeroSection';
import { FeaturesSection } from './FeaturesSection';
export const componentMap = {
'sections.hero': {
component: HeroSection,
schema: z.object({
__component: z.literal('sections.hero'),
title: z.string(),
subtitle: z.string().optional(),
}),
},
'sections.features': {
component: FeaturesSection,
schema: z.object({
__component: z.literal('sections.features'),
features: z.array(z.object({
title: z.string(),
description: z.string(),
})),
}),
},
};
// app/api/revalidate/route.ts
import { createStrapiRevalidator } from 'strapi-nextgen-framework';
const handler = createStrapiRevalidator({
secret: process.env.STRAPI_WEBHOOK_SECRET!,
tagMap: {
'api::page.page': 'strapi_page',
'api::blog-post.blog-post': 'strapi_collection_blogPosts',
},
logging: true,
});
export { handler as POST };
// app/api/preview/route.ts
import { createPreviewHandler } from 'strapi-nextgen-framework';
const handler = createPreviewHandler({
secret: process.env.STRAPI_PREVIEW_SECRET!,
logging: true,
});
export { handler as GET };
// app/api/exit-preview/route.ts
import { createExitPreviewHandler } from 'strapi-nextgen-framework';
const handler = createExitPreviewHandler();
export { handler as GET };
# Install dependencies
npm install
# Build the library
npm run build
# Run tests
npm test
# Type checking
npm run type-check
# Lint
npm run lint
📚 For complete API documentation with examples and troubleshooting, visit API Reference
createStrapiSDK(config)Creates a Strapi SDK instance with automatic cache tagging.
Parameters:
url (string, required): Strapi GraphQL endpoint URLtoken (string, optional): API token for authenticated requestsdefaultLocale (string, optional): Default locale for i18n querieslogging (object, optional): Logging configuration
queries (boolean): Log all GraphQL queriescacheTags (boolean): Log cache tagsvalidation ('error' | 'warn' | 'silent'): Validation error loggingReturns: StrapiSDK instance
Methods:
getPage<T>(slug, options?): Fetch a single page by sluggetCollection<T>(collectionName, options?): Fetch a collectiongetGlobal<T>(globalName, options?): Fetch a global singletonrawQuery<T>(query, variables?, options?): Execute custom GraphQL queryExample:
const sdk = createStrapiSDK({
url: 'http://localhost:1337/graphql',
token: 'your-token',
defaultLocale: 'en',
});
const page = await sdk.getPage('home', { locale: 'fr' });
<StrapiRenderer />Renders Strapi dynamic zones with automatic component mapping and error boundaries.
Props:
data (array, required): Array of Strapi componentsmap (ComponentMap, required): Component mapping objectvalidation ('error' | 'warn' | 'silent', optional): Validation modefallback (ReactNode, optional): Fallback UI for errorsonError (function, optional): Error callbackExample:
<StrapiRenderer
data={page.attributes.dynamicZone}
map={componentMap}
validation="warn"
fallback={<div>Something went wrong</div>}
onError={(error, errorInfo, componentType) => {
console.error('Component error:', componentType, error);
}}
/>
generateStrapiMetadata(seoData, defaults?)Generates Next.js metadata from Strapi SEO component.
Parameters:
seoData (StrapiSEO | null | undefined): Strapi SEO component datadefaults (Partial, optional): Default metadata valuesReturns: Next.js Metadata object
Example:
export async function generateMetadata({ params }) {
const page = await strapiClient.getPage(params.slug);
return generateStrapiMetadata(page.attributes.seo, {
metadataBase: new URL('https://example.com'),
});
}
<StrapiImage />Optimized image component with next/image integration.
Props:
data (StrapiMedia, required): Strapi media objectnextImageProps (ImageProps, optional): Additional next/image propsfallback (string, optional): Fallback image URLExample:
<StrapiImage
data={page.attributes.hero.image}
nextImageProps={{
priority: true,
className: 'rounded-lg',
fill: true,
}}
fallback="/placeholder.jpg"
/>
createStrapiRevalidator(config)Creates a webhook handler for on-demand ISR revalidation.
Parameters:
secret (string, required): Webhook secret for validationtagMap (object, optional): Custom model-to-tag mappinglogging (boolean, optional): Enable loggingReturns: Next.js Route Handler
Example:
const handler = createStrapiRevalidator({
secret: process.env.STRAPI_WEBHOOK_SECRET!,
tagMap: {
'api::page.page': 'strapi_page',
},
logging: true,
});
export { handler as POST };
createPreviewHandler(config)Creates a preview mode handler for draft content.
Parameters:
secret (string, required): Preview secret for validationlogging (boolean, optional): Enable loggingReturns: Next.js Route Handler
Usage: /api/preview?secret=YOUR_SECRET&slug=/about
createExitPreviewHandler()Creates a handler to disable preview mode.
Returns: Next.js Route Handler
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
GPL-3.0 © fuqom
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
Note: This framework requires Strapi v4 with GraphQL plugin and Next.js 14+ with App Router.
FAQs
Production-ready, type-safe framework bridging Strapi v4 CMS and Next.js 14+ App Router with automatic cache management, Error Boundaries, and SEO optimization
We found that strapi-nextgen-framework demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.