rkk-next 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rohit Kumar Kundu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,248 @@
1
+ # 🚀 rkk-next
2
+
3
+ > **SEO, Performance & Routing SDK for Next.js**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/rkk-next.svg)](https://www.npmjs.com/package/rkk-next)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
8
+
9
+ rkk-next is an opinionated Next.js SDK that helps you build **SEO-optimized**, **blazing fast**, and **scalable** applications with better routing, caching, and performance defaults.
10
+
11
+ ✨ **Built for Next.js Pages Router & App Router**
12
+ 🎯 **Ideal for:** Startups, Landing Pages, Web3 Dashboards, SaaS, Hackathons
13
+
14
+ ## ✨ Features
15
+
16
+ ### 🔍 SEO Optimization
17
+ - ✅ Centralized meta management (OpenGraph, Twitter Cards)
18
+ - ✅ JSON-LD structured data (Schema.org)
19
+ - ✅ Canonical URL handling
20
+ - ✅ SEO-safe defaults & best practices
21
+
22
+ ### ⚡ Routing Optimization
23
+ - ✅ Intelligent route prefetching (hover-based)
24
+ - ✅ Network-aware prefetching
25
+ - ✅ Route change observer with performance metrics
26
+ - ✅ Analytics-ready routing events
27
+
28
+ ### 🚀 Performance Boost
29
+ - ✅ Lazy loading for heavy components
30
+ - ✅ Optimized image wrapper (SEO + performance)
31
+ - ✅ Cache & CDN header presets
32
+ - ✅ Edge-friendly caching strategies
33
+ - ✅ Security headers included
34
+
35
+ ### 📊 Analytics
36
+ - ✅ Web Vitals tracking (LCP, FID, CLS, etc.)
37
+ - ✅ Route navigation analytics
38
+ - ✅ Performance monitoring
39
+
40
+ 📦 Installation
41
+ npm install rkk-next
42
+
43
+
44
+ or
45
+
46
+ yarn add rkk-next
47
+
48
+ 🧠 Basic Usage
49
+ 1️⃣ SEO Meta Manager
50
+ import { MetaManager } from "rkk-next";
51
+
52
+ export default function Home() {
53
+ return (
54
+ <>
55
+ <MetaManager
56
+ title="Home | My App"
57
+ description="SEO optimized Next.js app using rkk-next"
58
+ keywords="Next.js, SEO, Performance"
59
+ image="/og.png"
60
+ siteName="My App"
61
+ />
62
+
63
+ <h1>Hello World</h1>
64
+ </>
65
+ );
66
+ }
67
+
68
+ 2️⃣ JSON-LD (Schema.org)
69
+ import { JsonLd } from "rkk-next";
70
+
71
+ <JsonLd
72
+ type="WebSite"
73
+ data={{
74
+ name: "My App",
75
+ url: "https://myapp.com",
76
+ }}
77
+ />
78
+
79
+ 🔗 Smart Routing
80
+ SmartLink (Enhanced next/link)
81
+ import { SmartLink } from "rkk-next";
82
+
83
+ <SmartLink href="/dashboard">
84
+ Go to Dashboard
85
+ </SmartLink>
86
+
87
+
88
+ ✔ Prefetch on hover
89
+ ✔ Network-aware
90
+ ✔ SEO-safe <a> tag
91
+
92
+ Route Observer
93
+ import { observeRoutes } from "rkk-next";
94
+
95
+ observeRoutes((event) => {
96
+ console.log(event.url, event.duration);
97
+ });
98
+
99
+ 🖼️ Image Optimization
100
+ import { OptimizedImage } from "rkk-next";
101
+
102
+ <OptimizedImage
103
+ src="/hero.png"
104
+ alt="Landing page hero image"
105
+ width={1200}
106
+ height={630}
107
+ priority
108
+ />
109
+
110
+
111
+ ✔ SEO-safe alt enforcement
112
+ ✔ Responsive sizes
113
+ ✔ LCP optimized
114
+
115
+ 💤 Lazy Loading
116
+ import { lazyImport } from "rkk-next";
117
+
118
+ const Chart = lazyImport(() => import("./Chart"));
119
+
120
+ export default function Dashboard() {
121
+ return <Chart />;
122
+ }
123
+
124
+ 🧠 Intelligent Prefetching
125
+ import { prefetchRoute, isFastConnection } from "rkk-next";
126
+
127
+ prefetchRoute("/dashboard", {
128
+ condition: isFastConnection,
129
+ });
130
+
131
+ 🗄️ Cache Headers
132
+
133
+ Use directly inside next.config.js:
134
+
135
+ const {
136
+ LONG_TERM_CACHE,
137
+ EDGE_CACHE,
138
+ NO_CACHE,
139
+ applyCache,
140
+ } = require("rkk-next");
141
+
142
+ module.exports = {
143
+ async headers() {
144
+ return [
145
+ applyCache("/_next/static/:path*", LONG_TERM_CACHE),
146
+ applyCache("/api/public/:path*", EDGE_CACHE),
147
+ applyCache("/dashboard/:path*", NO_CACHE),
148
+ ];
149
+ },
150
+ };
151
+
152
+ ## 🧩 Supported Next.js Versions
153
+
154
+ | Feature | Pages Router | App Router |
155
+ |-------------------|--------------|------------|
156
+ | MetaManager | ✅ | ✅ (via generateAppMetadata) |
157
+ | JsonLd | ✅ | ✅ |
158
+ | SmartLink | ✅ | ⚠️ (use for internal links only) |
159
+ | Routing Observer | ✅ | ⚠️ (Pages Router recommended) |
160
+ | OptimizedImage | ✅ | ✅ |
161
+ | Lazy Loading | ✅ | ✅ |
162
+ | Cache Headers | ✅ | ✅ |
163
+ | Web Vitals | ✅ | ✅ |
164
+
165
+ **Minimum Requirements:**
166
+ - Next.js >= 12.0.0
167
+ - React >= 17.0.0
168
+ - TypeScript >= 4.5.0 (optional but recommended)
169
+ 🛠️ Best Practices
170
+
171
+ Use MetaManager on every page
172
+
173
+ Avoid lazy loading LCP elements
174
+
175
+ Use SmartLink for internal navigation
176
+
177
+ Enable cache headers for static assets
178
+
179
+ Always provide alt text for images
180
+
181
+ ## 🧑‍💻 Author
182
+
183
+ **Rohit Kumar Kundu**
184
+ 🎓 B.Tech CSE | Web3 & Next.js Developer
185
+ 🔗 [GitHub](https://github.com/ROHIT8759) | [LinkedIn](https://linkedin.com/in/rohit-kumar-kundu)
186
+
187
+ ## 📚 Documentation
188
+
189
+ - 📖 [Full Documentation](./docs/DOCS.md)
190
+ - 🚀 [Quick Start Guide](./docs/QUICKSTART.md)
191
+ - 📝 [API Reference](./docs/DOCS.md#api-reference)
192
+ - 💡 [Examples](./examples/)
193
+
194
+ ## 🤝 Contributing
195
+
196
+ We welcome contributions! See [CONTRIBUTING.md](./docs/CONTRIBUTING.md) for guidelines.
197
+
198
+ 1. Fork the repository
199
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
200
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
201
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
202
+ 5. Open a Pull Request
203
+
204
+ ## 🚀 Next Steps
205
+
206
+ - [ ] Add App Router `generateMetadata` helper
207
+ - [ ] Expand Web Vitals analytics integration
208
+ - [ ] Create demo app showcase
209
+ - [ ] Add Lighthouse CI integration
210
+ - [ ] Video tutorials & guides
211
+
212
+ ## 📄 License
213
+
214
+ MIT License © 2025 [Rohit Kumar Kundu](https://github.com/ROHIT8759)
215
+
216
+ Free to use, modify, and distribute. See [LICENSE](./LICENSE) for details.
217
+
218
+ ## ⭐ Support the Project
219
+
220
+ If you find rkk-next helpful:
221
+
222
+ - ⭐ **Star the repo** on GitHub
223
+ - 🐛 **Report issues** to help improve the SDK
224
+ - 🤝 **Contribute** with PRs and feature ideas
225
+ - 📢 **Share** with other Next.js developers
226
+ - 💬 **Join discussions** and share your use cases
227
+
228
+ ---
229
+
230
+ **Made with ❤️ for the Next.js community**
231
+
232
+ [Get Started](./docs/QUICKSTART.md) | [Documentation](./docs/DOCS.md) | [Examples](./examples/) | [Report Issue](https://github.com/ROHIT8759/rkk-next/issues)
233
+
234
+ NPM publish
235
+
236
+ If you want, I can now:
237
+
238
+ ✔ Review this README
239
+
240
+ ✔ Add badges (npm, downloads)
241
+
242
+ ✔ Prepare NPM publish checklist
243
+
244
+ ✔ Create example Next.js app
245
+
246
+ ✔ Final SDK audit before release
247
+
248
+ Just tell me 👍
@@ -0,0 +1,2 @@
1
+ import { NextWebVitalsMetric } from "next/app";
2
+ export declare function reportWebVitals(metric: NextWebVitalsMetric): void;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reportWebVitals = reportWebVitals;
4
+ function reportWebVitals(metric) {
5
+ const { id, name, value } = metric;
6
+ console.log("[Vitals]", name, value);
7
+ // future: send to analytics
8
+ }
@@ -0,0 +1,12 @@
1
+ export * from "./seo/MetaManager";
2
+ export * from "./seo/JsonLd";
3
+ export * from "./seo/defaults";
4
+ export * from "./seo/appMetadata";
5
+ export * from "./routing/SmartLink";
6
+ export * from "./routing/prefetch";
7
+ export * from "./routing/RouteObserver";
8
+ export * from "./performance/ImageOptimizer";
9
+ export * from "./performance/Lazy";
10
+ export * from "./performance/cacheHeaders";
11
+ export * from "./performance/securityHeaders";
12
+ export * from "./analytics/webVitals";
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ // SEO
18
+ __exportStar(require("./seo/MetaManager"), exports);
19
+ __exportStar(require("./seo/JsonLd"), exports);
20
+ __exportStar(require("./seo/defaults"), exports);
21
+ __exportStar(require("./seo/appMetadata"), exports);
22
+ // Routing
23
+ __exportStar(require("./routing/SmartLink"), exports);
24
+ __exportStar(require("./routing/prefetch"), exports);
25
+ __exportStar(require("./routing/RouteObserver"), exports);
26
+ // Performance
27
+ __exportStar(require("./performance/ImageOptimizer"), exports);
28
+ __exportStar(require("./performance/Lazy"), exports);
29
+ __exportStar(require("./performance/cacheHeaders"), exports);
30
+ __exportStar(require("./performance/securityHeaders"), exports);
31
+ // Analytics
32
+ __exportStar(require("./analytics/webVitals"), exports);
@@ -0,0 +1,16 @@
1
+ import { ImageProps } from "next/image";
2
+ import React from "react";
3
+ export type OptimizedImageProps = ImageProps & {
4
+ /** Override default quality (1–100) */
5
+ quality?: number;
6
+ /** Enable priority loading (LCP images) */
7
+ priority?: boolean;
8
+ /** Fallback alt text (SEO safety) */
9
+ alt: string;
10
+ };
11
+ /**
12
+ * OptimizedImage
13
+ * SEO-first wrapper around next/image
14
+ */
15
+ export declare const OptimizedImage: React.FC<OptimizedImageProps>;
16
+ export default OptimizedImage;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.OptimizedImage = void 0;
7
+ const image_1 = __importDefault(require("next/image"));
8
+ const react_1 = __importDefault(require("react"));
9
+ /**
10
+ * OptimizedImage
11
+ * SEO-first wrapper around next/image
12
+ */
13
+ const OptimizedImage = ({ quality = 80, priority = false, alt, ...props }) => {
14
+ if (!alt) {
15
+ if (process.env.NODE_ENV !== "production") {
16
+ console.warn("[next-optimize-sdk] OptimizedImage requires alt text for SEO");
17
+ }
18
+ }
19
+ return (react_1.default.createElement(image_1.default, { ...props, alt: alt, quality: quality, priority: priority, loading: priority ? "eager" : "lazy", sizes: props.sizes ||
20
+ "(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw", placeholder: props.placeholder || "empty" }));
21
+ };
22
+ exports.OptimizedImage = OptimizedImage;
23
+ exports.default = exports.OptimizedImage;
@@ -0,0 +1,19 @@
1
+ import { Loader } from "next/dynamic";
2
+ import React from "react";
3
+ export type LazyOptions<P = {}> = {
4
+ /** Custom loading component */
5
+ loading?: React.ComponentType;
6
+ /** Enable / disable SSR */
7
+ ssr?: boolean;
8
+ /** Delay before showing loading component (ms) */
9
+ delay?: number;
10
+ };
11
+ /**
12
+ * Lazy-load a React component with Next.js dynamic import
13
+ * Optimized for performance and bundle size reduction
14
+ */
15
+ export declare function lazyImport<P = {}>(loader: Loader<P>, options?: LazyOptions<P>): React.ComponentType<P>;
16
+ /**
17
+ * Simple fallback loading component
18
+ */
19
+ export declare const DefaultLoader: React.FC;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DefaultLoader = void 0;
7
+ exports.lazyImport = lazyImport;
8
+ const dynamic_1 = __importDefault(require("next/dynamic"));
9
+ const react_1 = __importDefault(require("react"));
10
+ /**
11
+ * Lazy-load a React component with Next.js dynamic import
12
+ * Optimized for performance and bundle size reduction
13
+ */
14
+ function lazyImport(loader, options = {}) {
15
+ const { loading: LoadingComponent, ssr = false, delay = 200, } = options;
16
+ const dynamicOptions = {
17
+ ssr,
18
+ loading: LoadingComponent
19
+ ? () => react_1.default.createElement(LoadingComponent, null)
20
+ : () => null,
21
+ };
22
+ return (0, dynamic_1.default)(loader, dynamicOptions);
23
+ }
24
+ /**
25
+ * Simple fallback loading component
26
+ */
27
+ const DefaultLoader = () => (react_1.default.createElement("div", { style: {
28
+ padding: "1rem",
29
+ textAlign: "center",
30
+ opacity: 0.7,
31
+ fontSize: "0.9rem",
32
+ } }, "Loading\u2026"));
33
+ exports.DefaultLoader = DefaultLoader;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Cache header presets for Next.js
3
+ * Centralized caching strategy for SEO & performance
4
+ */
5
+ export type CacheHeader = {
6
+ key: string;
7
+ value: string;
8
+ };
9
+ /**
10
+ * Long-term cache
11
+ * Best for static assets (JS, CSS, fonts, images)
12
+ */
13
+ export declare const LONG_TERM_CACHE: CacheHeader[];
14
+ /**
15
+ * Short-term cache
16
+ * Best for ISR pages or frequently updated content
17
+ */
18
+ export declare const SHORT_TERM_CACHE: CacheHeader[];
19
+ /**
20
+ * No cache
21
+ * Best for dashboards, auth, user-specific pages
22
+ */
23
+ export declare const NO_CACHE: CacheHeader[];
24
+ /**
25
+ * Edge / CDN optimized cache
26
+ */
27
+ export declare const EDGE_CACHE: CacheHeader[];
28
+ /**
29
+ * Helper function to apply cache headers
30
+ * directly inside next.config.js
31
+ */
32
+ export declare function applyCache(source: string, headers: CacheHeader[]): {
33
+ source: string;
34
+ headers: CacheHeader[];
35
+ };
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /**
3
+ * Cache header presets for Next.js
4
+ * Centralized caching strategy for SEO & performance
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.EDGE_CACHE = exports.NO_CACHE = exports.SHORT_TERM_CACHE = exports.LONG_TERM_CACHE = void 0;
8
+ exports.applyCache = applyCache;
9
+ /**
10
+ * Long-term cache
11
+ * Best for static assets (JS, CSS, fonts, images)
12
+ */
13
+ exports.LONG_TERM_CACHE = [
14
+ {
15
+ key: "Cache-Control",
16
+ value: "public, max-age=31536000, immutable",
17
+ },
18
+ ];
19
+ /**
20
+ * Short-term cache
21
+ * Best for ISR pages or frequently updated content
22
+ */
23
+ exports.SHORT_TERM_CACHE = [
24
+ {
25
+ key: "Cache-Control",
26
+ value: "public, max-age=60, stale-while-revalidate=300",
27
+ },
28
+ ];
29
+ /**
30
+ * No cache
31
+ * Best for dashboards, auth, user-specific pages
32
+ */
33
+ exports.NO_CACHE = [
34
+ {
35
+ key: "Cache-Control",
36
+ value: "no-store, no-cache, must-revalidate, proxy-revalidate",
37
+ },
38
+ {
39
+ key: "Pragma",
40
+ value: "no-cache",
41
+ },
42
+ {
43
+ key: "Expires",
44
+ value: "0",
45
+ },
46
+ ];
47
+ /**
48
+ * Edge / CDN optimized cache
49
+ */
50
+ exports.EDGE_CACHE = [
51
+ {
52
+ key: "Cache-Control",
53
+ value: "public, s-maxage=86400, stale-while-revalidate=604800",
54
+ },
55
+ ];
56
+ /**
57
+ * Helper function to apply cache headers
58
+ * directly inside next.config.js
59
+ */
60
+ function applyCache(source, headers) {
61
+ return {
62
+ source,
63
+ headers,
64
+ };
65
+ }
@@ -0,0 +1,4 @@
1
+ export declare const SECURITY_HEADERS: {
2
+ key: string;
3
+ value: string;
4
+ }[];
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SECURITY_HEADERS = void 0;
4
+ exports.SECURITY_HEADERS = [
5
+ {
6
+ key: "X-Frame-Options",
7
+ value: "DENY",
8
+ },
9
+ {
10
+ key: "X-Content-Type-Options",
11
+ value: "nosniff",
12
+ },
13
+ {
14
+ key: "Referrer-Policy",
15
+ value: "strict-origin-when-cross-origin",
16
+ },
17
+ ];
@@ -0,0 +1,24 @@
1
+ export type RouteChangeEvent = {
2
+ /** Current route URL */
3
+ url: string;
4
+ /** Previous route URL */
5
+ previousUrl: string;
6
+ /** Navigation duration in ms */
7
+ duration: number;
8
+ /** Timestamp when navigation finished */
9
+ timestamp: number;
10
+ };
11
+ type RouteObserverCallback = (event: RouteChangeEvent) => void;
12
+ /**
13
+ * Observe Next.js route changes with performance metrics
14
+ */
15
+ export declare function observeRoutes(callback: RouteObserverCallback): (() => void) | undefined;
16
+ /**
17
+ * SEO helper – update document title on route change
18
+ */
19
+ export declare function observeTitle(titleFormatter: (path: string) => string): void;
20
+ /**
21
+ * Analytics helper – plug any analytics provider
22
+ */
23
+ export declare function observeAnalytics(track: (data: RouteChangeEvent) => void): void;
24
+ export {};
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.observeRoutes = observeRoutes;
7
+ exports.observeTitle = observeTitle;
8
+ exports.observeAnalytics = observeAnalytics;
9
+ const router_1 = __importDefault(require("next/router"));
10
+ let previousUrl = "";
11
+ let startTime = 0;
12
+ /**
13
+ * Observe Next.js route changes with performance metrics
14
+ */
15
+ function observeRoutes(callback) {
16
+ if (typeof window === "undefined")
17
+ return;
18
+ const handleStart = (url) => {
19
+ startTime = performance.now();
20
+ };
21
+ const handleComplete = (url) => {
22
+ const duration = performance.now() - startTime;
23
+ callback({
24
+ url,
25
+ previousUrl,
26
+ duration,
27
+ timestamp: Date.now(),
28
+ });
29
+ previousUrl = url;
30
+ };
31
+ router_1.default.events.on("routeChangeStart", handleStart);
32
+ router_1.default.events.on("routeChangeComplete", handleComplete);
33
+ return () => {
34
+ router_1.default.events.off("routeChangeStart", handleStart);
35
+ router_1.default.events.off("routeChangeComplete", handleComplete);
36
+ };
37
+ }
38
+ /**
39
+ * SEO helper – update document title on route change
40
+ */
41
+ function observeTitle(titleFormatter) {
42
+ if (typeof window === "undefined")
43
+ return;
44
+ observeRoutes(({ url }) => {
45
+ document.title = titleFormatter(url);
46
+ });
47
+ }
48
+ /**
49
+ * Analytics helper – plug any analytics provider
50
+ */
51
+ function observeAnalytics(track) {
52
+ observeRoutes(track);
53
+ }
@@ -0,0 +1,17 @@
1
+ import { LinkProps } from "next/link";
2
+ import React, { AnchorHTMLAttributes } from "react";
3
+ type AnchorProps = AnchorHTMLAttributes<HTMLAnchorElement>;
4
+ export type SmartLinkProps = LinkProps & AnchorProps & {
5
+ /** Enable intelligent prefetching */
6
+ prefetchOnHover?: boolean;
7
+ /** Delay before prefetch (ms) */
8
+ prefetchDelay?: number;
9
+ /** Disable prefetch completely */
10
+ disablePrefetch?: boolean;
11
+ };
12
+ /**
13
+ * SmartLink
14
+ * SEO-safe, accessibility-friendly, and performance-optimized
15
+ */
16
+ export declare const SmartLink: React.FC<SmartLinkProps>;
17
+ export default SmartLink;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.SmartLink = void 0;
40
+ const link_1 = __importDefault(require("next/link"));
41
+ const react_1 = __importStar(require("react"));
42
+ const prefetch_1 = require("./prefetch");
43
+ /**
44
+ * SmartLink
45
+ * SEO-safe, accessibility-friendly, and performance-optimized
46
+ */
47
+ const SmartLink = ({ href, children, prefetchOnHover = true, prefetchDelay = 150, disablePrefetch = false, onMouseEnter, ...props }) => {
48
+ const handleMouseEnter = (0, react_1.useCallback)((e) => {
49
+ onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(e);
50
+ if (disablePrefetch || !prefetchOnHover)
51
+ return;
52
+ if (typeof href === "string" && (0, prefetch_1.isFastConnection)()) {
53
+ (0, prefetch_1.prefetchRoute)(href, {
54
+ delay: prefetchDelay,
55
+ });
56
+ }
57
+ }, [href, disablePrefetch, prefetchOnHover, prefetchDelay, onMouseEnter]);
58
+ return (react_1.default.createElement(link_1.default, { href: href, passHref: true, legacyBehavior: true },
59
+ react_1.default.createElement("a", { ...props, onMouseEnter: handleMouseEnter }, children)));
60
+ };
61
+ exports.SmartLink = SmartLink;
62
+ exports.default = exports.SmartLink;
@@ -0,0 +1,25 @@
1
+ type PrefetchOptions = {
2
+ /** Enable or disable prefetch globally */
3
+ enabled?: boolean;
4
+ /** Delay before prefetch starts (ms) */
5
+ delay?: number;
6
+ /** Only prefetch when user is idle */
7
+ idleOnly?: boolean;
8
+ /** Custom condition (e.g. network check) */
9
+ condition?: () => boolean;
10
+ };
11
+ /**
12
+ * Intelligent route prefetching for Next.js
13
+ * Prefetches routes when user intent is detected
14
+ */
15
+ export declare function prefetchRoute(href: string, options?: PrefetchOptions): void;
16
+ /**
17
+ * Prefetch multiple routes safely
18
+ */
19
+ export declare function prefetchRoutes(routes: string[], options?: PrefetchOptions): void;
20
+ /**
21
+ * Network-aware prefetch condition
22
+ * Prevents prefetch on slow connections
23
+ */
24
+ export declare function isFastConnection(): boolean;
25
+ export {};
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.prefetchRoute = prefetchRoute;
7
+ exports.prefetchRoutes = prefetchRoutes;
8
+ exports.isFastConnection = isFastConnection;
9
+ const router_1 = __importDefault(require("next/router"));
10
+ /**
11
+ * Intelligent route prefetching for Next.js
12
+ * Prefetches routes when user intent is detected
13
+ */
14
+ function prefetchRoute(href, options = {}) {
15
+ const { enabled = true, delay = 200, idleOnly = true, condition, } = options;
16
+ if (!enabled)
17
+ return;
18
+ if (typeof window === "undefined")
19
+ return;
20
+ if (condition && !condition())
21
+ return;
22
+ const startPrefetch = () => {
23
+ try {
24
+ router_1.default.prefetch(href);
25
+ }
26
+ catch (err) {
27
+ console.warn("[next-optimize-sdk] Prefetch failed:", err);
28
+ }
29
+ };
30
+ if (idleOnly && "requestIdleCallback" in window) {
31
+ window.requestIdleCallback(() => {
32
+ setTimeout(startPrefetch, delay);
33
+ });
34
+ }
35
+ else {
36
+ setTimeout(startPrefetch, delay);
37
+ }
38
+ }
39
+ /**
40
+ * Prefetch multiple routes safely
41
+ */
42
+ function prefetchRoutes(routes, options) {
43
+ routes.forEach((route) => prefetchRoute(route, options));
44
+ }
45
+ /**
46
+ * Network-aware prefetch condition
47
+ * Prevents prefetch on slow connections
48
+ */
49
+ function isFastConnection() {
50
+ if (typeof navigator === "undefined")
51
+ return true;
52
+ const connection = navigator.connection ||
53
+ navigator.mozConnection ||
54
+ navigator.webkitConnection;
55
+ if (!connection)
56
+ return true;
57
+ return !["slow-2g", "2g"].includes(connection.effectiveType);
58
+ }
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ export type JsonLdProps<T extends object> = {
3
+ /** Schema.org type (e.g. WebSite, Article, Product, FAQPage) */
4
+ type: string;
5
+ /** Schema data object */
6
+ data: T;
7
+ /** Optional ID for deduplication */
8
+ id?: string;
9
+ };
10
+ /**
11
+ * Generic JSON-LD injector for Next.js
12
+ * Safe for SSR, SEO-compliant, and reusable
13
+ */
14
+ export declare function JsonLd<T extends object>({ type, data, id, }: JsonLdProps<T>): React.JSX.Element | null;
15
+ export default JsonLd;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.JsonLd = JsonLd;
7
+ const head_1 = __importDefault(require("next/head"));
8
+ const react_1 = __importDefault(require("react"));
9
+ /**
10
+ * Generic JSON-LD injector for Next.js
11
+ * Safe for SSR, SEO-compliant, and reusable
12
+ */
13
+ function JsonLd({ type, data, id, }) {
14
+ if (!data)
15
+ return null;
16
+ const jsonLd = {
17
+ "@context": "https://schema.org",
18
+ "@type": type,
19
+ ...data,
20
+ };
21
+ return (react_1.default.createElement(head_1.default, null,
22
+ react_1.default.createElement("script", { id: id, type: "application/ld+json", dangerouslySetInnerHTML: {
23
+ __html: JSON.stringify(jsonLd),
24
+ } })));
25
+ }
26
+ exports.default = JsonLd;
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ export type MetaManagerProps = {
3
+ /** Page title */
4
+ title: string;
5
+ /** Meta description (important for SEO) */
6
+ description: string;
7
+ /** Optional keywords */
8
+ keywords?: string;
9
+ /** Canonical URL (auto-generated if not provided) */
10
+ canonicalUrl?: string;
11
+ /** Open Graph image URL */
12
+ image?: string;
13
+ /** Open Graph type */
14
+ type?: "website" | "article";
15
+ /** Robots meta */
16
+ noIndex?: boolean;
17
+ /** Site name for Open Graph */
18
+ siteName?: string;
19
+ /** Author name */
20
+ author?: string;
21
+ /** Twitter username (without @) */
22
+ twitterHandle?: string;
23
+ };
24
+ export declare const MetaManager: React.FC<MetaManagerProps>;
25
+ export default MetaManager;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MetaManager = void 0;
7
+ const head_1 = __importDefault(require("next/head"));
8
+ const router_1 = require("next/router");
9
+ const react_1 = __importDefault(require("react"));
10
+ const MetaManager = ({ title, description, keywords, canonicalUrl, image, type = "website", noIndex = false, siteName = "My Website", author, twitterHandle, }) => {
11
+ const router = (0, router_1.useRouter)();
12
+ // Auto canonical URL fallback
13
+ const canonical = canonicalUrl ||
14
+ (typeof window !== "undefined"
15
+ ? `${window.location.origin}${router.asPath}`
16
+ : "");
17
+ return (react_1.default.createElement(head_1.default, null,
18
+ react_1.default.createElement("title", null, title),
19
+ react_1.default.createElement("meta", { name: "description", content: description }),
20
+ keywords && react_1.default.createElement("meta", { name: "keywords", content: keywords }),
21
+ author && react_1.default.createElement("meta", { name: "author", content: author }),
22
+ react_1.default.createElement("meta", { name: "robots", content: noIndex ? "noindex, nofollow" : "index, follow" }),
23
+ canonical && react_1.default.createElement("link", { rel: "canonical", href: canonical }),
24
+ react_1.default.createElement("meta", { property: "og:type", content: type }),
25
+ react_1.default.createElement("meta", { property: "og:title", content: title }),
26
+ react_1.default.createElement("meta", { property: "og:description", content: description }),
27
+ react_1.default.createElement("meta", { property: "og:site_name", content: siteName }),
28
+ canonical && react_1.default.createElement("meta", { property: "og:url", content: canonical }),
29
+ image && react_1.default.createElement("meta", { property: "og:image", content: image }),
30
+ react_1.default.createElement("meta", { name: "twitter:card", content: "summary_large_image" }),
31
+ twitterHandle && (react_1.default.createElement("meta", { name: "twitter:site", content: `@${twitterHandle}` })),
32
+ react_1.default.createElement("meta", { name: "twitter:title", content: title }),
33
+ react_1.default.createElement("meta", { name: "twitter:description", content: description }),
34
+ image && react_1.default.createElement("meta", { name: "twitter:image", content: image }),
35
+ react_1.default.createElement("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }),
36
+ react_1.default.createElement("meta", { name: "theme-color", content: "#000000" })));
37
+ };
38
+ exports.MetaManager = MetaManager;
39
+ exports.default = exports.MetaManager;
@@ -0,0 +1,13 @@
1
+ export declare function generateAppMetadata({ title, description, image, }: {
2
+ title?: string;
3
+ description?: string;
4
+ image?: string;
5
+ }): {
6
+ title: string;
7
+ description: string;
8
+ openGraph: {
9
+ title: string | undefined;
10
+ description: string | undefined;
11
+ images: string[];
12
+ };
13
+ };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateAppMetadata = generateAppMetadata;
4
+ const defaults_1 = require("./defaults");
5
+ function generateAppMetadata({ title, description, image, }) {
6
+ return {
7
+ title: title || defaults_1.SEO_DEFAULTS.defaultTitle,
8
+ description: description || defaults_1.SEO_DEFAULTS.defaultDescription,
9
+ openGraph: {
10
+ title,
11
+ description,
12
+ images: image ? [image] : [],
13
+ },
14
+ };
15
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Global SEO defaults for next-optimize-sdk
3
+ * These values can be overridden per page using MetaManager
4
+ */
5
+ export type SeoDefaults = {
6
+ siteName: string;
7
+ titleTemplate: string;
8
+ defaultTitle: string;
9
+ defaultDescription: string;
10
+ defaultKeywords: string;
11
+ defaultImage: string;
12
+ siteUrl: string;
13
+ twitterHandle?: string;
14
+ themeColor?: string;
15
+ };
16
+ /**
17
+ * Default SEO configuration
18
+ * Override this in your app if needed
19
+ */
20
+ export declare const SEO_DEFAULTS: SeoDefaults;
21
+ /**
22
+ * Helper to generate full title using template
23
+ */
24
+ export declare function getSeoTitle(title?: string, template?: string): string;
25
+ /**
26
+ * Helper to generate canonical URL
27
+ */
28
+ export declare function getCanonicalUrl(path: string): string;
29
+ /**
30
+ * Merge custom SEO config with defaults
31
+ */
32
+ export declare function mergeSeoDefaults(overrides?: Partial<SeoDefaults>): SeoDefaults;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /**
3
+ * Global SEO defaults for next-optimize-sdk
4
+ * These values can be overridden per page using MetaManager
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.SEO_DEFAULTS = void 0;
8
+ exports.getSeoTitle = getSeoTitle;
9
+ exports.getCanonicalUrl = getCanonicalUrl;
10
+ exports.mergeSeoDefaults = mergeSeoDefaults;
11
+ /**
12
+ * Default SEO configuration
13
+ * Override this in your app if needed
14
+ */
15
+ exports.SEO_DEFAULTS = {
16
+ siteName: "My Website",
17
+ titleTemplate: "%s | My Website",
18
+ defaultTitle: "My Website",
19
+ defaultDescription: "A modern, fast, and SEO-optimized Next.js application.",
20
+ defaultKeywords: "Next.js, SEO, Web Performance, React, Optimization",
21
+ defaultImage: "/og-image.png",
22
+ siteUrl: "https://example.com",
23
+ twitterHandle: "",
24
+ themeColor: "#000000",
25
+ };
26
+ /**
27
+ * Helper to generate full title using template
28
+ */
29
+ function getSeoTitle(title, template = exports.SEO_DEFAULTS.titleTemplate) {
30
+ if (!title)
31
+ return exports.SEO_DEFAULTS.defaultTitle;
32
+ return template.replace("%s", title);
33
+ }
34
+ /**
35
+ * Helper to generate canonical URL
36
+ */
37
+ function getCanonicalUrl(path) {
38
+ if (!path.startsWith("/"))
39
+ path = `/${path}`;
40
+ return `${exports.SEO_DEFAULTS.siteUrl}${path}`;
41
+ }
42
+ /**
43
+ * Merge custom SEO config with defaults
44
+ */
45
+ function mergeSeoDefaults(overrides = {}) {
46
+ return {
47
+ ...exports.SEO_DEFAULTS,
48
+ ...overrides,
49
+ };
50
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "rkk-next",
3
+ "version": "1.0.0",
4
+ "description": "SEO, routing and performance optimization SDK for Next.js",
5
+ "author": "Rohit Kumar Kundu",
6
+ "license": "MIT",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/ROHIT8759/rkk-next.git"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/ROHIT8759/rkk-next/issues"
18
+ },
19
+ "homepage": "https://github.com/ROHIT8759/rkk-next#readme",
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "dev": "tsc --watch",
23
+ "prepublishOnly": "npm run build",
24
+ "test": "echo \"Tests coming soon\" && exit 0"
25
+ },
26
+ "peerDependencies": {
27
+ "next": ">=12",
28
+ "react": ">=17",
29
+ "react-dom": ">=17"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^20.10.0",
33
+ "@types/react": "^18.2.45",
34
+ "@types/react-dom": "^18.2.18",
35
+ "typescript": "^5.3.3"
36
+ },
37
+ "keywords": [
38
+ "nextjs",
39
+ "seo",
40
+ "performance",
41
+ "routing",
42
+ "optimization",
43
+ "web-vitals",
44
+ "sdk",
45
+ "rkk-next",
46
+ "react",
47
+ "meta-tags",
48
+ "json-ld",
49
+ "prefetch"
50
+ ]
51
+ }