@json-render/next 0.15.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 +201 -0
- package/README.md +103 -0
- package/dist/chunk-37T7IDU5.js +104 -0
- package/dist/chunk-37T7IDU5.js.map +1 -0
- package/dist/chunk-KWYBSJZC.mjs +104 -0
- package/dist/chunk-KWYBSJZC.mjs.map +1 -0
- package/dist/index.d.mts +314 -0
- package/dist/index.d.ts +314 -0
- package/dist/index.js +135 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +135 -0
- package/dist/index.mjs.map +1 -0
- package/dist/page-renderer-client.d.mts +25 -0
- package/dist/page-renderer-client.d.ts +25 -0
- package/dist/page-renderer-client.js +9 -0
- package/dist/page-renderer-client.js.map +1 -0
- package/dist/page-renderer-client.mjs +9 -0
- package/dist/page-renderer-client.mjs.map +1 -0
- package/dist/server.d.mts +358 -0
- package/dist/server.d.ts +358 -0
- package/dist/server.js +538 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +506 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +71 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React, { ReactNode } from 'react';
|
|
3
|
+
import { ComponentRegistry, ComponentRenderProps } from '@json-render/react';
|
|
4
|
+
export { ActionFn, Actions, BaseComponentProps, ComponentContext, ComponentFn, ComponentRegistry, ComponentRenderProps, Components, EventHandle, SetState, StateModel } from '@json-render/react';
|
|
5
|
+
export { PageRenderer, PageRendererProps } from './page-renderer-client.mjs';
|
|
6
|
+
import { Spec } from '@json-render/core';
|
|
7
|
+
export { Spec, StateStore, createStateStore } from '@json-render/core';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Context value holding the component registry, action handlers,
|
|
11
|
+
* and the Next.js router navigate function.
|
|
12
|
+
*/
|
|
13
|
+
interface NextAppContextValue {
|
|
14
|
+
registry: ComponentRegistry;
|
|
15
|
+
handlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
|
|
16
|
+
navigate: (href: string) => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Props for NextAppProvider.
|
|
20
|
+
*/
|
|
21
|
+
interface NextAppProviderProps {
|
|
22
|
+
/** Component registry for rendering */
|
|
23
|
+
registry: ComponentRegistry;
|
|
24
|
+
/** Action handlers */
|
|
25
|
+
handlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
|
|
26
|
+
children: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Provider that holds the component registry and action handlers
|
|
30
|
+
* for the entire json-render Next.js application.
|
|
31
|
+
*
|
|
32
|
+
* Wrap your root layout with this provider:
|
|
33
|
+
*
|
|
34
|
+
* ```tsx
|
|
35
|
+
* // app/[[...slug]]/layout.tsx
|
|
36
|
+
* import { NextAppProvider } from "@json-render/next";
|
|
37
|
+
* import { registry, handlers } from "@/lib/registry";
|
|
38
|
+
*
|
|
39
|
+
* export default function Layout({ children }) {
|
|
40
|
+
* return (
|
|
41
|
+
* <html><body>
|
|
42
|
+
* <NextAppProvider registry={registry} handlers={handlers}>
|
|
43
|
+
* {children}
|
|
44
|
+
* </NextAppProvider>
|
|
45
|
+
* </body></html>
|
|
46
|
+
* );
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
declare function NextAppProvider({ registry, handlers, children, }: NextAppProviderProps): react_jsx_runtime.JSX.Element;
|
|
51
|
+
/**
|
|
52
|
+
* Hook to access the NextApp context.
|
|
53
|
+
* Must be used within a NextAppProvider.
|
|
54
|
+
*/
|
|
55
|
+
declare function useNextApp(): NextAppContextValue;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Props for NextErrorBoundary.
|
|
59
|
+
*/
|
|
60
|
+
interface NextErrorBoundaryProps {
|
|
61
|
+
/** The error that occurred */
|
|
62
|
+
error: Error & {
|
|
63
|
+
digest?: string;
|
|
64
|
+
};
|
|
65
|
+
/** Function to attempt re-rendering the page */
|
|
66
|
+
reset: () => void;
|
|
67
|
+
/** Optional error UI spec from the matched route */
|
|
68
|
+
errorSpec?: Spec | null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Error boundary component for json-render Next.js apps.
|
|
72
|
+
*
|
|
73
|
+
* If the matched route defines an `error` spec, it renders that.
|
|
74
|
+
* Otherwise renders a minimal default error UI.
|
|
75
|
+
*
|
|
76
|
+
* Must be used in a file with `"use client"` directive (Next.js requirement).
|
|
77
|
+
*/
|
|
78
|
+
declare function NextErrorBoundary({ error, reset, errorSpec, }: NextErrorBoundaryProps): react_jsx_runtime.JSX.Element;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Props for NextLoading.
|
|
82
|
+
*/
|
|
83
|
+
interface NextLoadingProps {
|
|
84
|
+
/** Optional loading UI spec */
|
|
85
|
+
loadingSpec?: Spec | null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Loading component for json-render Next.js apps.
|
|
89
|
+
*
|
|
90
|
+
* If a loading spec is provided, it will be rendered by the PageRenderer.
|
|
91
|
+
* Otherwise renders a minimal default loading indicator.
|
|
92
|
+
*
|
|
93
|
+
* Note: Since Next.js loading.tsx is static (no params), this renders
|
|
94
|
+
* a generic loading state. Route-specific loading can be achieved with
|
|
95
|
+
* Suspense boundaries in page content.
|
|
96
|
+
*/
|
|
97
|
+
declare function NextLoading({ loadingSpec: _loadingSpec }: NextLoadingProps): react_jsx_runtime.JSX.Element;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Not-found component for json-render Next.js apps.
|
|
101
|
+
*
|
|
102
|
+
* Renders when the pathname does not match any route in the spec.
|
|
103
|
+
*/
|
|
104
|
+
declare function NextNotFound(): react_jsx_runtime.JSX.Element;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Props expected by the Link component in json-render specs.
|
|
108
|
+
*/
|
|
109
|
+
interface LinkProps {
|
|
110
|
+
/** The target URL or route path */
|
|
111
|
+
href: string;
|
|
112
|
+
/** Whether to replace the current history entry */
|
|
113
|
+
replace?: boolean;
|
|
114
|
+
/** Whether to prefetch the linked route */
|
|
115
|
+
prefetch?: boolean;
|
|
116
|
+
/** CSS class name */
|
|
117
|
+
className?: string;
|
|
118
|
+
/** Inline styles */
|
|
119
|
+
style?: React.CSSProperties;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Built-in Link component for json-render Next.js specs.
|
|
123
|
+
*
|
|
124
|
+
* Wraps `next/link` for client-side navigation between routes.
|
|
125
|
+
*
|
|
126
|
+
* Usage in a spec:
|
|
127
|
+
* ```json
|
|
128
|
+
* {
|
|
129
|
+
* "type": "Link",
|
|
130
|
+
* "props": { "href": "/about" },
|
|
131
|
+
* "children": ["link-text"]
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
declare function Link({ element, children }: ComponentRenderProps<LinkProps>): react_jsx_runtime.JSX.Element;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Metadata for Next.js pages and layouts.
|
|
139
|
+
* Maps to Next.js's Metadata type.
|
|
140
|
+
*/
|
|
141
|
+
interface NextMetadata {
|
|
142
|
+
/** Page title — string or template config */
|
|
143
|
+
title?: string | {
|
|
144
|
+
/** Default title when no child overrides */
|
|
145
|
+
default: string;
|
|
146
|
+
/** Template string, use %s for the page title (e.g. "%s | My App") */
|
|
147
|
+
template?: string;
|
|
148
|
+
/** Absolute title that ignores parent templates */
|
|
149
|
+
absolute?: string;
|
|
150
|
+
};
|
|
151
|
+
/** Meta description */
|
|
152
|
+
description?: string;
|
|
153
|
+
/** Keywords for SEO */
|
|
154
|
+
keywords?: string[];
|
|
155
|
+
/** Open Graph metadata */
|
|
156
|
+
openGraph?: {
|
|
157
|
+
title?: string;
|
|
158
|
+
description?: string;
|
|
159
|
+
images?: string | string[];
|
|
160
|
+
type?: string;
|
|
161
|
+
url?: string;
|
|
162
|
+
siteName?: string;
|
|
163
|
+
locale?: string;
|
|
164
|
+
};
|
|
165
|
+
/** Twitter card metadata */
|
|
166
|
+
twitter?: {
|
|
167
|
+
card?: "summary" | "summary_large_image" | "app" | "player";
|
|
168
|
+
title?: string;
|
|
169
|
+
description?: string;
|
|
170
|
+
images?: string | string[];
|
|
171
|
+
creator?: string;
|
|
172
|
+
site?: string;
|
|
173
|
+
};
|
|
174
|
+
/** Robots directives */
|
|
175
|
+
robots?: string | {
|
|
176
|
+
index?: boolean;
|
|
177
|
+
follow?: boolean;
|
|
178
|
+
};
|
|
179
|
+
/** Canonical URL */
|
|
180
|
+
alternates?: {
|
|
181
|
+
canonical?: string;
|
|
182
|
+
};
|
|
183
|
+
/** Favicon and icons */
|
|
184
|
+
icons?: string | {
|
|
185
|
+
icon?: string;
|
|
186
|
+
apple?: string;
|
|
187
|
+
shortcut?: string;
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* A route definition within a NextAppSpec.
|
|
192
|
+
*/
|
|
193
|
+
interface NextRouteSpec {
|
|
194
|
+
/** Page content — standard json-render element tree */
|
|
195
|
+
page: Spec;
|
|
196
|
+
/** Per-route metadata for SEO */
|
|
197
|
+
metadata?: NextMetadata;
|
|
198
|
+
/** Layout key referencing an entry in NextAppSpec.layouts */
|
|
199
|
+
layout?: string;
|
|
200
|
+
/** Loading state element tree (rendered during Suspense) */
|
|
201
|
+
loading?: Spec;
|
|
202
|
+
/** Error state element tree */
|
|
203
|
+
error?: Spec;
|
|
204
|
+
/** Not-found element tree (for dynamic routes that don't match data) */
|
|
205
|
+
notFound?: Spec;
|
|
206
|
+
/** Server-side data loader name (references loaders in createNextApp) */
|
|
207
|
+
loader?: string;
|
|
208
|
+
/** Static params for generateStaticParams */
|
|
209
|
+
staticParams?: Record<string, string>[];
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* The full application spec for @json-render/next.
|
|
213
|
+
*
|
|
214
|
+
* Describes an entire Next.js application: routes, pages, layouts,
|
|
215
|
+
* metadata, and server-side data loading.
|
|
216
|
+
*
|
|
217
|
+
* Routes are keyed by URL patterns using Next.js conventions:
|
|
218
|
+
* - `"/"` — exact match
|
|
219
|
+
* - `"/blog/[slug]"` — dynamic segment
|
|
220
|
+
* - `"/docs/[...path]"` — catch-all segment
|
|
221
|
+
* - `"/settings/[[...path]]"` — optional catch-all segment
|
|
222
|
+
*/
|
|
223
|
+
interface NextAppSpec {
|
|
224
|
+
/** Root-level metadata applied to all routes (layouts can override) */
|
|
225
|
+
metadata?: NextMetadata;
|
|
226
|
+
/** Route definitions keyed by URL pattern */
|
|
227
|
+
routes: Record<string, NextRouteSpec>;
|
|
228
|
+
/**
|
|
229
|
+
* Reusable layout element trees. Each layout spec must include a
|
|
230
|
+
* `Slot` component type where page content will be injected.
|
|
231
|
+
*/
|
|
232
|
+
layouts?: Record<string, Spec>;
|
|
233
|
+
/** Global initial state shared across all routes */
|
|
234
|
+
state?: Record<string, unknown>;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Result of matching a pathname against the spec's routes.
|
|
238
|
+
*/
|
|
239
|
+
interface MatchedRoute {
|
|
240
|
+
/** The matched route spec */
|
|
241
|
+
route: NextRouteSpec;
|
|
242
|
+
/** The URL pattern that matched (e.g. "/blog/[slug]") */
|
|
243
|
+
pattern: string;
|
|
244
|
+
/** Extracted route parameters (e.g. { slug: "hello-world" }) */
|
|
245
|
+
params: Record<string, string | string[]>;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Server-side data loader function signature.
|
|
249
|
+
* Receives route params and returns data to merge into initial state.
|
|
250
|
+
*/
|
|
251
|
+
type LoaderFn = (params: Record<string, string | string[]>) => Promise<Record<string, unknown>> | Record<string, unknown>;
|
|
252
|
+
/**
|
|
253
|
+
* Options for createNextApp.
|
|
254
|
+
*/
|
|
255
|
+
interface CreateNextAppOptions {
|
|
256
|
+
/** The application spec */
|
|
257
|
+
spec: NextAppSpec | (() => NextAppSpec | Promise<NextAppSpec>);
|
|
258
|
+
/** Server-side data loaders keyed by name */
|
|
259
|
+
loaders?: Record<string, LoaderFn>;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Data returned by getPageData for client-side rendering.
|
|
263
|
+
*/
|
|
264
|
+
interface PageData {
|
|
265
|
+
/** Page element tree spec */
|
|
266
|
+
spec: Spec;
|
|
267
|
+
/** Initial state (merged from spec.state, global state, and loader data) */
|
|
268
|
+
initialState?: Record<string, unknown>;
|
|
269
|
+
/** Optional layout element tree spec */
|
|
270
|
+
layoutSpec?: Spec | null;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* The result of createNextApp — exports for Next.js route files.
|
|
274
|
+
*/
|
|
275
|
+
interface NextAppExports {
|
|
276
|
+
/**
|
|
277
|
+
* Resolve page data for a given set of params.
|
|
278
|
+
* Returns null if no route matches (caller should call notFound()).
|
|
279
|
+
*
|
|
280
|
+
* Use this in your Server Component page.tsx alongside a client wrapper
|
|
281
|
+
* that renders PageRenderer:
|
|
282
|
+
*
|
|
283
|
+
* ```tsx
|
|
284
|
+
* // app/[[...slug]]/page.tsx
|
|
285
|
+
* import { getPageData, generateMetadata, generateStaticParams } from "@/lib/app";
|
|
286
|
+
* import { WebsiteRenderer } from "./renderer";
|
|
287
|
+
*
|
|
288
|
+
* export { generateMetadata, generateStaticParams };
|
|
289
|
+
*
|
|
290
|
+
* export default async function Page({ params }) {
|
|
291
|
+
* const data = await getPageData({ params });
|
|
292
|
+
* if (!data) notFound();
|
|
293
|
+
* return <WebsiteRenderer {...data} />;
|
|
294
|
+
* }
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
getPageData: (props: {
|
|
298
|
+
params: Promise<{
|
|
299
|
+
slug?: string[];
|
|
300
|
+
}>;
|
|
301
|
+
}) => Promise<PageData | null>;
|
|
302
|
+
/** generateMetadata function for page.tsx */
|
|
303
|
+
generateMetadata: (props: {
|
|
304
|
+
params: Promise<{
|
|
305
|
+
slug?: string[];
|
|
306
|
+
}>;
|
|
307
|
+
}) => Promise<Record<string, unknown>>;
|
|
308
|
+
/** generateStaticParams function for page.tsx */
|
|
309
|
+
generateStaticParams: () => Promise<{
|
|
310
|
+
slug: string[];
|
|
311
|
+
}[]>;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export { type CreateNextAppOptions, Link, type LinkProps, type LoaderFn, type MatchedRoute, type NextAppContextValue, type NextAppExports, NextAppProvider, type NextAppProviderProps, type NextAppSpec, NextErrorBoundary, type NextErrorBoundaryProps, NextLoading, type NextLoadingProps, type NextMetadata, NextNotFound, type NextRouteSpec, type PageData, useNextApp };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React, { ReactNode } from 'react';
|
|
3
|
+
import { ComponentRegistry, ComponentRenderProps } from '@json-render/react';
|
|
4
|
+
export { ActionFn, Actions, BaseComponentProps, ComponentContext, ComponentFn, ComponentRegistry, ComponentRenderProps, Components, EventHandle, SetState, StateModel } from '@json-render/react';
|
|
5
|
+
export { PageRenderer, PageRendererProps } from './page-renderer-client.js';
|
|
6
|
+
import { Spec } from '@json-render/core';
|
|
7
|
+
export { Spec, StateStore, createStateStore } from '@json-render/core';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Context value holding the component registry, action handlers,
|
|
11
|
+
* and the Next.js router navigate function.
|
|
12
|
+
*/
|
|
13
|
+
interface NextAppContextValue {
|
|
14
|
+
registry: ComponentRegistry;
|
|
15
|
+
handlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
|
|
16
|
+
navigate: (href: string) => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Props for NextAppProvider.
|
|
20
|
+
*/
|
|
21
|
+
interface NextAppProviderProps {
|
|
22
|
+
/** Component registry for rendering */
|
|
23
|
+
registry: ComponentRegistry;
|
|
24
|
+
/** Action handlers */
|
|
25
|
+
handlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
|
|
26
|
+
children: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Provider that holds the component registry and action handlers
|
|
30
|
+
* for the entire json-render Next.js application.
|
|
31
|
+
*
|
|
32
|
+
* Wrap your root layout with this provider:
|
|
33
|
+
*
|
|
34
|
+
* ```tsx
|
|
35
|
+
* // app/[[...slug]]/layout.tsx
|
|
36
|
+
* import { NextAppProvider } from "@json-render/next";
|
|
37
|
+
* import { registry, handlers } from "@/lib/registry";
|
|
38
|
+
*
|
|
39
|
+
* export default function Layout({ children }) {
|
|
40
|
+
* return (
|
|
41
|
+
* <html><body>
|
|
42
|
+
* <NextAppProvider registry={registry} handlers={handlers}>
|
|
43
|
+
* {children}
|
|
44
|
+
* </NextAppProvider>
|
|
45
|
+
* </body></html>
|
|
46
|
+
* );
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
declare function NextAppProvider({ registry, handlers, children, }: NextAppProviderProps): react_jsx_runtime.JSX.Element;
|
|
51
|
+
/**
|
|
52
|
+
* Hook to access the NextApp context.
|
|
53
|
+
* Must be used within a NextAppProvider.
|
|
54
|
+
*/
|
|
55
|
+
declare function useNextApp(): NextAppContextValue;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Props for NextErrorBoundary.
|
|
59
|
+
*/
|
|
60
|
+
interface NextErrorBoundaryProps {
|
|
61
|
+
/** The error that occurred */
|
|
62
|
+
error: Error & {
|
|
63
|
+
digest?: string;
|
|
64
|
+
};
|
|
65
|
+
/** Function to attempt re-rendering the page */
|
|
66
|
+
reset: () => void;
|
|
67
|
+
/** Optional error UI spec from the matched route */
|
|
68
|
+
errorSpec?: Spec | null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Error boundary component for json-render Next.js apps.
|
|
72
|
+
*
|
|
73
|
+
* If the matched route defines an `error` spec, it renders that.
|
|
74
|
+
* Otherwise renders a minimal default error UI.
|
|
75
|
+
*
|
|
76
|
+
* Must be used in a file with `"use client"` directive (Next.js requirement).
|
|
77
|
+
*/
|
|
78
|
+
declare function NextErrorBoundary({ error, reset, errorSpec, }: NextErrorBoundaryProps): react_jsx_runtime.JSX.Element;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Props for NextLoading.
|
|
82
|
+
*/
|
|
83
|
+
interface NextLoadingProps {
|
|
84
|
+
/** Optional loading UI spec */
|
|
85
|
+
loadingSpec?: Spec | null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Loading component for json-render Next.js apps.
|
|
89
|
+
*
|
|
90
|
+
* If a loading spec is provided, it will be rendered by the PageRenderer.
|
|
91
|
+
* Otherwise renders a minimal default loading indicator.
|
|
92
|
+
*
|
|
93
|
+
* Note: Since Next.js loading.tsx is static (no params), this renders
|
|
94
|
+
* a generic loading state. Route-specific loading can be achieved with
|
|
95
|
+
* Suspense boundaries in page content.
|
|
96
|
+
*/
|
|
97
|
+
declare function NextLoading({ loadingSpec: _loadingSpec }: NextLoadingProps): react_jsx_runtime.JSX.Element;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Not-found component for json-render Next.js apps.
|
|
101
|
+
*
|
|
102
|
+
* Renders when the pathname does not match any route in the spec.
|
|
103
|
+
*/
|
|
104
|
+
declare function NextNotFound(): react_jsx_runtime.JSX.Element;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Props expected by the Link component in json-render specs.
|
|
108
|
+
*/
|
|
109
|
+
interface LinkProps {
|
|
110
|
+
/** The target URL or route path */
|
|
111
|
+
href: string;
|
|
112
|
+
/** Whether to replace the current history entry */
|
|
113
|
+
replace?: boolean;
|
|
114
|
+
/** Whether to prefetch the linked route */
|
|
115
|
+
prefetch?: boolean;
|
|
116
|
+
/** CSS class name */
|
|
117
|
+
className?: string;
|
|
118
|
+
/** Inline styles */
|
|
119
|
+
style?: React.CSSProperties;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Built-in Link component for json-render Next.js specs.
|
|
123
|
+
*
|
|
124
|
+
* Wraps `next/link` for client-side navigation between routes.
|
|
125
|
+
*
|
|
126
|
+
* Usage in a spec:
|
|
127
|
+
* ```json
|
|
128
|
+
* {
|
|
129
|
+
* "type": "Link",
|
|
130
|
+
* "props": { "href": "/about" },
|
|
131
|
+
* "children": ["link-text"]
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
declare function Link({ element, children }: ComponentRenderProps<LinkProps>): react_jsx_runtime.JSX.Element;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Metadata for Next.js pages and layouts.
|
|
139
|
+
* Maps to Next.js's Metadata type.
|
|
140
|
+
*/
|
|
141
|
+
interface NextMetadata {
|
|
142
|
+
/** Page title — string or template config */
|
|
143
|
+
title?: string | {
|
|
144
|
+
/** Default title when no child overrides */
|
|
145
|
+
default: string;
|
|
146
|
+
/** Template string, use %s for the page title (e.g. "%s | My App") */
|
|
147
|
+
template?: string;
|
|
148
|
+
/** Absolute title that ignores parent templates */
|
|
149
|
+
absolute?: string;
|
|
150
|
+
};
|
|
151
|
+
/** Meta description */
|
|
152
|
+
description?: string;
|
|
153
|
+
/** Keywords for SEO */
|
|
154
|
+
keywords?: string[];
|
|
155
|
+
/** Open Graph metadata */
|
|
156
|
+
openGraph?: {
|
|
157
|
+
title?: string;
|
|
158
|
+
description?: string;
|
|
159
|
+
images?: string | string[];
|
|
160
|
+
type?: string;
|
|
161
|
+
url?: string;
|
|
162
|
+
siteName?: string;
|
|
163
|
+
locale?: string;
|
|
164
|
+
};
|
|
165
|
+
/** Twitter card metadata */
|
|
166
|
+
twitter?: {
|
|
167
|
+
card?: "summary" | "summary_large_image" | "app" | "player";
|
|
168
|
+
title?: string;
|
|
169
|
+
description?: string;
|
|
170
|
+
images?: string | string[];
|
|
171
|
+
creator?: string;
|
|
172
|
+
site?: string;
|
|
173
|
+
};
|
|
174
|
+
/** Robots directives */
|
|
175
|
+
robots?: string | {
|
|
176
|
+
index?: boolean;
|
|
177
|
+
follow?: boolean;
|
|
178
|
+
};
|
|
179
|
+
/** Canonical URL */
|
|
180
|
+
alternates?: {
|
|
181
|
+
canonical?: string;
|
|
182
|
+
};
|
|
183
|
+
/** Favicon and icons */
|
|
184
|
+
icons?: string | {
|
|
185
|
+
icon?: string;
|
|
186
|
+
apple?: string;
|
|
187
|
+
shortcut?: string;
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* A route definition within a NextAppSpec.
|
|
192
|
+
*/
|
|
193
|
+
interface NextRouteSpec {
|
|
194
|
+
/** Page content — standard json-render element tree */
|
|
195
|
+
page: Spec;
|
|
196
|
+
/** Per-route metadata for SEO */
|
|
197
|
+
metadata?: NextMetadata;
|
|
198
|
+
/** Layout key referencing an entry in NextAppSpec.layouts */
|
|
199
|
+
layout?: string;
|
|
200
|
+
/** Loading state element tree (rendered during Suspense) */
|
|
201
|
+
loading?: Spec;
|
|
202
|
+
/** Error state element tree */
|
|
203
|
+
error?: Spec;
|
|
204
|
+
/** Not-found element tree (for dynamic routes that don't match data) */
|
|
205
|
+
notFound?: Spec;
|
|
206
|
+
/** Server-side data loader name (references loaders in createNextApp) */
|
|
207
|
+
loader?: string;
|
|
208
|
+
/** Static params for generateStaticParams */
|
|
209
|
+
staticParams?: Record<string, string>[];
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* The full application spec for @json-render/next.
|
|
213
|
+
*
|
|
214
|
+
* Describes an entire Next.js application: routes, pages, layouts,
|
|
215
|
+
* metadata, and server-side data loading.
|
|
216
|
+
*
|
|
217
|
+
* Routes are keyed by URL patterns using Next.js conventions:
|
|
218
|
+
* - `"/"` — exact match
|
|
219
|
+
* - `"/blog/[slug]"` — dynamic segment
|
|
220
|
+
* - `"/docs/[...path]"` — catch-all segment
|
|
221
|
+
* - `"/settings/[[...path]]"` — optional catch-all segment
|
|
222
|
+
*/
|
|
223
|
+
interface NextAppSpec {
|
|
224
|
+
/** Root-level metadata applied to all routes (layouts can override) */
|
|
225
|
+
metadata?: NextMetadata;
|
|
226
|
+
/** Route definitions keyed by URL pattern */
|
|
227
|
+
routes: Record<string, NextRouteSpec>;
|
|
228
|
+
/**
|
|
229
|
+
* Reusable layout element trees. Each layout spec must include a
|
|
230
|
+
* `Slot` component type where page content will be injected.
|
|
231
|
+
*/
|
|
232
|
+
layouts?: Record<string, Spec>;
|
|
233
|
+
/** Global initial state shared across all routes */
|
|
234
|
+
state?: Record<string, unknown>;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Result of matching a pathname against the spec's routes.
|
|
238
|
+
*/
|
|
239
|
+
interface MatchedRoute {
|
|
240
|
+
/** The matched route spec */
|
|
241
|
+
route: NextRouteSpec;
|
|
242
|
+
/** The URL pattern that matched (e.g. "/blog/[slug]") */
|
|
243
|
+
pattern: string;
|
|
244
|
+
/** Extracted route parameters (e.g. { slug: "hello-world" }) */
|
|
245
|
+
params: Record<string, string | string[]>;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Server-side data loader function signature.
|
|
249
|
+
* Receives route params and returns data to merge into initial state.
|
|
250
|
+
*/
|
|
251
|
+
type LoaderFn = (params: Record<string, string | string[]>) => Promise<Record<string, unknown>> | Record<string, unknown>;
|
|
252
|
+
/**
|
|
253
|
+
* Options for createNextApp.
|
|
254
|
+
*/
|
|
255
|
+
interface CreateNextAppOptions {
|
|
256
|
+
/** The application spec */
|
|
257
|
+
spec: NextAppSpec | (() => NextAppSpec | Promise<NextAppSpec>);
|
|
258
|
+
/** Server-side data loaders keyed by name */
|
|
259
|
+
loaders?: Record<string, LoaderFn>;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Data returned by getPageData for client-side rendering.
|
|
263
|
+
*/
|
|
264
|
+
interface PageData {
|
|
265
|
+
/** Page element tree spec */
|
|
266
|
+
spec: Spec;
|
|
267
|
+
/** Initial state (merged from spec.state, global state, and loader data) */
|
|
268
|
+
initialState?: Record<string, unknown>;
|
|
269
|
+
/** Optional layout element tree spec */
|
|
270
|
+
layoutSpec?: Spec | null;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* The result of createNextApp — exports for Next.js route files.
|
|
274
|
+
*/
|
|
275
|
+
interface NextAppExports {
|
|
276
|
+
/**
|
|
277
|
+
* Resolve page data for a given set of params.
|
|
278
|
+
* Returns null if no route matches (caller should call notFound()).
|
|
279
|
+
*
|
|
280
|
+
* Use this in your Server Component page.tsx alongside a client wrapper
|
|
281
|
+
* that renders PageRenderer:
|
|
282
|
+
*
|
|
283
|
+
* ```tsx
|
|
284
|
+
* // app/[[...slug]]/page.tsx
|
|
285
|
+
* import { getPageData, generateMetadata, generateStaticParams } from "@/lib/app";
|
|
286
|
+
* import { WebsiteRenderer } from "./renderer";
|
|
287
|
+
*
|
|
288
|
+
* export { generateMetadata, generateStaticParams };
|
|
289
|
+
*
|
|
290
|
+
* export default async function Page({ params }) {
|
|
291
|
+
* const data = await getPageData({ params });
|
|
292
|
+
* if (!data) notFound();
|
|
293
|
+
* return <WebsiteRenderer {...data} />;
|
|
294
|
+
* }
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
getPageData: (props: {
|
|
298
|
+
params: Promise<{
|
|
299
|
+
slug?: string[];
|
|
300
|
+
}>;
|
|
301
|
+
}) => Promise<PageData | null>;
|
|
302
|
+
/** generateMetadata function for page.tsx */
|
|
303
|
+
generateMetadata: (props: {
|
|
304
|
+
params: Promise<{
|
|
305
|
+
slug?: string[];
|
|
306
|
+
}>;
|
|
307
|
+
}) => Promise<Record<string, unknown>>;
|
|
308
|
+
/** generateStaticParams function for page.tsx */
|
|
309
|
+
generateStaticParams: () => Promise<{
|
|
310
|
+
slug: string[];
|
|
311
|
+
}[]>;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export { type CreateNextAppOptions, Link, type LinkProps, type LoaderFn, type MatchedRoute, type NextAppContextValue, type NextAppExports, NextAppProvider, type NextAppProviderProps, type NextAppSpec, NextErrorBoundary, type NextErrorBoundaryProps, NextLoading, type NextLoadingProps, type NextMetadata, NextNotFound, type NextRouteSpec, type PageData, useNextApp };
|