@enonic/nextjs-adapter 0.13.0 → 1.0.0-RC1
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/ComponentRegistry.d.ts +2 -0
- package/ComponentRegistry.js +6 -0
- package/README.md +623 -8
- package/UrlProcessor.d.ts +2 -1
- package/UrlProcessor.js +26 -1
- package/guillotine/fetchContent.d.ts +1 -21
- package/guillotine/fetchContent.js +94 -41
- package/index.d.ts +3 -0
- package/index.js +3 -0
- package/package.json +15 -14
- package/server/ClearableFileCache.js +314 -0
- package/server/cache.js +129 -0
- package/server/index.js +114 -0
- package/utils.d.ts +3 -12
- package/utils.js +10 -23
- package/views/RichTextView.jsx +11 -4
package/ComponentRegistry.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export declare class ComponentRegistry {
|
|
|
49
49
|
static getParts(): [string, ComponentDefinition][];
|
|
50
50
|
static getLayouts(): [string, ComponentDefinition][];
|
|
51
51
|
static getPages(): [string, ComponentDefinition][];
|
|
52
|
+
static getContentTypes(): [string, ComponentDefinition][];
|
|
53
|
+
static getComponents(): [string, ComponentDefinition][];
|
|
52
54
|
static addContentType(name: string, obj: ComponentDefinition): void;
|
|
53
55
|
static getContentType(name: string): ComponentDefinition | undefined;
|
|
54
56
|
static addPage(name: string, obj: ComponentDefinition): void;
|
package/ComponentRegistry.js
CHANGED
|
@@ -76,6 +76,12 @@ export class ComponentRegistry {
|
|
|
76
76
|
static getPages() {
|
|
77
77
|
return Object.entries(this.pages);
|
|
78
78
|
}
|
|
79
|
+
static getContentTypes() {
|
|
80
|
+
return Object.entries(this.contentTypes);
|
|
81
|
+
}
|
|
82
|
+
static getComponents() {
|
|
83
|
+
return Object.entries(this.components);
|
|
84
|
+
}
|
|
79
85
|
static addContentType(name, obj) {
|
|
80
86
|
return ComponentRegistry.addType('contentType', name, obj);
|
|
81
87
|
}
|
package/README.md
CHANGED
|
@@ -2,33 +2,648 @@
|
|
|
2
2
|
|
|
3
3
|
> NextJS adapter with Guillotine support and basic views
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
---
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
10
|
npm i --save @enonic/nextjs-adapter
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
##
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
---
|
|
12
16
|
|
|
13
|
-
Just import required functions and
|
|
17
|
+
Just import required functions and views in your project:
|
|
14
18
|
|
|
15
19
|
```tsx
|
|
16
|
-
|
|
20
|
+
// all functions and interfaces are accessible at the library root
|
|
21
|
+
import {fetchContent} from "@enonic/nextjs-adapter";
|
|
17
22
|
|
|
23
|
+
// views are placed in a folder called `views` and are default exports in files
|
|
24
|
+
import MainView from "@enonic/nextjs-adapter/views/MainView"
|
|
25
|
+
|
|
26
|
+
// ...
|
|
27
|
+
const props = await fetchContent(path, context);
|
|
18
28
|
// ...
|
|
19
29
|
|
|
20
|
-
|
|
30
|
+
return <MainView {...props}/>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## API
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
### Functions
|
|
38
|
+
|
|
39
|
+
They are available at the library root at `@enonic/nextjs-adapter`
|
|
40
|
+
|
|
41
|
+
#### <a id="fetch-content"></a>`fetchContent(contentPath: string | string[], context: Context) => Promise<FetchContentResult>`
|
|
42
|
+
|
|
43
|
+
Fetches the content/component by path with component queries optimization, page structure as well as runtime info calculation. This is the
|
|
44
|
+
main method for querying content.
|
|
45
|
+
|
|
46
|
+
| Argument | Description |
|
|
47
|
+
|-----------|---------------------------------------|
|
|
48
|
+
| `path` | Path to content |
|
|
49
|
+
| `context` | Execution context provided by Next.js |
|
|
50
|
+
|
|
51
|
+
Usage:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import {fetchContent} from '@enonic/nextjs-adapter';
|
|
55
|
+
|
|
56
|
+
const response = fetchContent('/path/to/content', context);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Response type:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
type FetchContentResult = {
|
|
63
|
+
error?: {
|
|
64
|
+
code: string,
|
|
65
|
+
message: string
|
|
66
|
+
} | null;
|
|
67
|
+
data: Record<string, any> | null, // Result of the content query
|
|
68
|
+
common: Record<string, any> | null, // Result of the common query
|
|
69
|
+
meta: MetaData, // Runtime information
|
|
70
|
+
page: PageComponent | null, // The structure of the page (not present when rendering single component)
|
|
71
|
+
};
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
#### <a id="fetch-guillotine"></a>`fetchGuillotine(apiUrl: string, body: ContentApiBaseBody, headers?: {}) => Promise<GuillotineResult>`
|
|
77
|
+
|
|
78
|
+
Makes a custom request to Guillotine. Used by [fetchContent()](#fetch-content) method.
|
|
79
|
+
|
|
80
|
+
| Argument | Description |
|
|
81
|
+
|-----------|---------------------------------------------------------|
|
|
82
|
+
| `apiUrl` | Guillotine API URL |
|
|
83
|
+
| `body` | Body of the request |
|
|
84
|
+
| `headers` | Object of custom headers with string values. _Optional_ |
|
|
85
|
+
|
|
86
|
+
Usage:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
import {fetchGuillotine} from '@enonic/nextjs-adapter';
|
|
90
|
+
|
|
91
|
+
const body = {
|
|
92
|
+
query: 'qraphql query as string',
|
|
93
|
+
variables: {
|
|
94
|
+
foo: 'bar',
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const headers = {
|
|
99
|
+
'custom-header': 'header-value',
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const result = fetchGuillotine('http://domain:8000/graphql/api', body, headers);
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Response type:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
type GuillotineResult = {
|
|
109
|
+
error?: {
|
|
110
|
+
code: string,
|
|
111
|
+
message: string
|
|
112
|
+
} | null;
|
|
113
|
+
[dataKey: string]: any;
|
|
114
|
+
};
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
#### `fetchFromApi(apiUrl: string, body: ContentApiBaseBody, headers?: {}, method?: string) => Promise<any>`
|
|
120
|
+
|
|
121
|
+
Makes custom third-party service request. Used by the [fetchGuillotine()](#fetch-guillotine) method.
|
|
122
|
+
|
|
123
|
+
| Argument | Description |
|
|
124
|
+
|-----------|------------------------------------------------------------------------------------|
|
|
125
|
+
| `apiUrl` | Service API URL |
|
|
126
|
+
| `body` | Body of the request |
|
|
127
|
+
| `headers` | Object of custom headers with string values. _Optional_ |
|
|
128
|
+
| `method` | Method of the request: `HEAD`, `POST`, `GET`, etc. _Optional, defaults to `POST`._ |
|
|
129
|
+
|
|
130
|
+
Usage:
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
import {fetchFromApi} from '@enonic/nextjs-adapter';
|
|
134
|
+
|
|
135
|
+
const body = {
|
|
136
|
+
query: 'qraphql query as string',
|
|
137
|
+
variables: {
|
|
138
|
+
foo: 'bar',
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const headers = {
|
|
143
|
+
'custom-header': 'header-value',
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const result = fetchFromApi('http://domain:8000/graphql/api', body, headers, 'GET');
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
#### `getUrl(url: string, meta: MetaData) => string`
|
|
152
|
+
|
|
153
|
+
Converts an absolute URL to the relative one for current viewer (Next.js/Enonic XP).
|
|
154
|
+
|
|
155
|
+
> **INFO:** For your URLs to work both in Enonic XP and Next.js you need to:
|
|
156
|
+
> 1. Query absolute URLs from guillotine
|
|
157
|
+
> 2. Wrap them with `getUrl()` function in the views
|
|
158
|
+
|
|
159
|
+
| Argument | Description |
|
|
160
|
+
|----------|---------------------------------------------------------|
|
|
161
|
+
| `url` | URL you want to transform |
|
|
162
|
+
| `meta` | Runtime data returned by [fetchContent](#fetch-content) |
|
|
163
|
+
|
|
164
|
+
Usage:
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
import {getUrl} from '@enonic/nextjs-adapter';
|
|
168
|
+
|
|
169
|
+
const urlRelativeToViewer = getUrl('http://domain:8000/graphql/api', meta);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
#### <a id="rich-text-query"></a>`richTextQuery(fieldName: string) => string`
|
|
175
|
+
|
|
176
|
+
This is a utility function for querying for `RichTextData` needed for [RichTextView](#rich-text-view). It creates a graphql query string for
|
|
177
|
+
HTML area input type with given field name.
|
|
178
|
+
|
|
179
|
+
| Argument | Description |
|
|
180
|
+
|-------------|----------------------|
|
|
181
|
+
| `fieldName` | HTML area field name |
|
|
182
|
+
|
|
183
|
+
Usage:
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import {richTextQuery} from '@enonic/nextjs-adapter';
|
|
187
|
+
|
|
188
|
+
const query = `query($path:ID!){
|
|
189
|
+
guillotine {
|
|
190
|
+
get(key:$path) {
|
|
191
|
+
_path
|
|
192
|
+
type
|
|
193
|
+
${richTextQuery('htmlField')}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}`;
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### `ComponentRegistry`
|
|
200
|
+
|
|
201
|
+
Registry containing definitions of all components (i.e. pages, parts, layouts, macros, etc. ). It is used in the runtime by `nextjs-adapter`
|
|
202
|
+
to make component queries and render components. It has several public methods:
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
#### `setCommonQuery(query: SelectedQueryMaybeVariablesFunc): void`
|
|
207
|
+
|
|
208
|
+
Sets up a common query that is going to be executed along with component queries and passed to every component on the page.
|
|
209
|
+
|
|
210
|
+
| Argument | Description |
|
|
211
|
+
|----------|---------------------------------------|
|
|
212
|
+
| `query` | Common [query definition](#query-def) |
|
|
213
|
+
|
|
214
|
+
Usage:
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
import {ComponentRegistry} from '@enonic/nextjs-adapter';
|
|
218
|
+
|
|
219
|
+
const query = {
|
|
220
|
+
query: 'graphql query',
|
|
221
|
+
variables: (path, context, config) => {
|
|
222
|
+
return {
|
|
223
|
+
path: path + '/some/processing'
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
ComponentRegistry.setCommonQuery(query);
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
#### `getCommonQuery(): SelectedQueryMaybeVariablesFunc`
|
|
234
|
+
|
|
235
|
+
Gets the common query definition.
|
|
236
|
+
|
|
237
|
+
<a id="query-def"></a>Response type:
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
type SelectedQueryMaybeVariablesFunc =
|
|
241
|
+
string |
|
|
242
|
+
QueryGetter |
|
|
243
|
+
{
|
|
244
|
+
query: string | QueryGetter,
|
|
245
|
+
variables: VariablesGetter
|
|
246
|
+
} |
|
|
247
|
+
[string | QueryGetter, VariablesGetter];
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Usage:
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
import {ComponentRegistry} from '@enonic/nextjs-adapter';
|
|
254
|
+
|
|
255
|
+
const query = ComponentRegistry.getCommonQuery();
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
#### `getByComponent(component: PageComponent): ComponentDefinition | undefined`
|
|
261
|
+
|
|
262
|
+
Gets component definition from the ComponentRegistry.
|
|
263
|
+
|
|
264
|
+
| Argument | Description |
|
|
265
|
+
|-------------|--------------------------------------|
|
|
266
|
+
| `component` | Page component to get definition for |
|
|
267
|
+
|
|
268
|
+
Usage:
|
|
269
|
+
|
|
270
|
+
```tsx
|
|
271
|
+
import {ComponentRegistry} from '@enonic/nextjs-adapter';
|
|
272
|
+
|
|
273
|
+
const definition = ComponentRegistry.getByComponent(component);
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
<a id="comp-def"></a>Response type:
|
|
277
|
+
|
|
278
|
+
```tsx
|
|
279
|
+
interface ComponentDefinition {
|
|
280
|
+
catchAll?: boolean; // set automatically depending on the binding
|
|
281
|
+
query?: SelectedQueryMaybeVariablesFunc,
|
|
282
|
+
configQuery?: string,
|
|
283
|
+
processor?: DataProcessor,
|
|
284
|
+
view?: React.FunctionComponent<any>
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
#### `addMacro(name: string, obj: ComponentDefinition): void`
|
|
291
|
+
|
|
292
|
+
#### `addPart(name: string, obj: ComponentDefinition): void`
|
|
293
|
+
|
|
294
|
+
#### `addLayout(name: string, obj: ComponentDefinition): void`
|
|
295
|
+
|
|
296
|
+
#### `addCPage(name: string, obj: ComponentDefinition): void`
|
|
297
|
+
|
|
298
|
+
#### `addContentType(name: string, obj: ComponentDefinition): void`
|
|
299
|
+
|
|
300
|
+
#### `addComponent(name: string, obj: ComponentDefinition): void`
|
|
301
|
+
|
|
302
|
+
Saves the component definition in ComponentRegistry by name.
|
|
303
|
+
|
|
304
|
+
> **NOTE:** <a id="add-comp"></a>`addComponent` is used for defining general types of Enonic XP components by `nextjs-adapter` so you don't
|
|
305
|
+
> need to do it manually. Overriding default setup may break Enonic XP integration!
|
|
306
|
+
|
|
307
|
+
| Argument | Description |
|
|
308
|
+
|----------|-----------------------------------|
|
|
309
|
+
| `name` | Component name |
|
|
310
|
+
| `obj` | [Component definition](#comp-def) |
|
|
311
|
+
|
|
312
|
+
Usage:
|
|
313
|
+
|
|
314
|
+
```tsx
|
|
315
|
+
import {ComponentRegistry} from '@enonic/nextjs-adapter';
|
|
316
|
+
|
|
317
|
+
const definition = {}
|
|
318
|
+
|
|
319
|
+
ComponentRegistry.addMacro('macro-name', definition);
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
#### `getMacro(name: string): ComponentDefinition | undefined`
|
|
325
|
+
|
|
326
|
+
#### `getPart(name: string): ComponentDefinition | undefined`
|
|
327
|
+
|
|
328
|
+
#### `getLayout(name: string): ComponentDefinition | undefined`
|
|
329
|
+
|
|
330
|
+
#### `getPage(name: string): ComponentDefinition | undefined`
|
|
331
|
+
|
|
332
|
+
#### `getContentType(name: string): ComponentDefinition | undefined`
|
|
333
|
+
|
|
334
|
+
#### `getComponent(name: string): ComponentDefinition | undefined`
|
|
335
|
+
|
|
336
|
+
Gets the component definition stored in ComponentRegistry by its name.
|
|
337
|
+
|
|
338
|
+
> **NOTE:** Read [addComponent](#add-comp) note before using `getComponent`.
|
|
21
339
|
|
|
340
|
+
| Argument | Description |
|
|
341
|
+
|----------|----------------|
|
|
342
|
+
| `name` | Component name |
|
|
343
|
+
|
|
344
|
+
Usage:
|
|
345
|
+
|
|
346
|
+
```tsx
|
|
347
|
+
import {ComponentRegistry} from '@enonic/nextjs-adapter';
|
|
348
|
+
|
|
349
|
+
const definition = ComponentRegistry.getMacro('macro-name');
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
Response type: [component definition](#comp-def)
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
#### `getMacros(): ComponentDefinition[]`
|
|
357
|
+
|
|
358
|
+
#### `getParts(): ComponentDefinition[]`
|
|
359
|
+
|
|
360
|
+
#### `getLayouts(): ComponentDefinition[]`
|
|
361
|
+
|
|
362
|
+
#### `getPages(): ComponentDefinition[]`
|
|
363
|
+
|
|
364
|
+
#### `getContentTypes(): ComponentDefinition[]`
|
|
365
|
+
|
|
366
|
+
#### `getComponents(): ComponentDefinition[]`
|
|
367
|
+
|
|
368
|
+
Gets all component definitions stored in ComponentRegistry.
|
|
369
|
+
|
|
370
|
+
> **NOTE:** Read [addComponent](#add-comp) note before using `getComponents`.
|
|
371
|
+
|
|
372
|
+
Usage:
|
|
373
|
+
|
|
374
|
+
```tsx
|
|
375
|
+
import {ComponentRegistry} from '@enonic/nextjs-adapter';
|
|
376
|
+
|
|
377
|
+
const macros = ComponentRegistry.getMacros();
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Response type: List of [component definitions](#comp-def)
|
|
381
|
+
|
|
382
|
+
### `UrlProcessor`
|
|
383
|
+
|
|
384
|
+
Helper singleton for processing URLs.
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
#### <a id="process"></a>`static process(url: string, meta: MetaData): string`
|
|
389
|
+
|
|
390
|
+
Processes the absolute URL to become relative for the current viewer, while keeping in mind Next.js assets and Enonic XP binary content
|
|
391
|
+
links
|
|
392
|
+
|
|
393
|
+
> **NOTE:** There is an alias to this function called `getUrl()` available at `@enonic/nextjs-adapter`
|
|
394
|
+
|
|
395
|
+
| Argument | Description |
|
|
396
|
+
|----------|---------------------------------------------------------|
|
|
397
|
+
| `url` | Absolute URL |
|
|
398
|
+
| `meta` | Runtime data returned by [fetchContent](#fetch-content) |
|
|
399
|
+
|
|
400
|
+
Usage:
|
|
401
|
+
|
|
402
|
+
```tsx
|
|
403
|
+
import {UrlProcessor} from '@enonic/nextjs-adapter';
|
|
404
|
+
|
|
405
|
+
const url = UrlProcessor.process('http://www.some.site.com/url/to/content', meta);
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
#### `static processSrcSet(srcset: string, meta: MetaData): string`
|
|
411
|
+
|
|
412
|
+
Processes the image srcset attribute to transform each URL with [`process`](#process) method
|
|
413
|
+
|
|
414
|
+
| Argument | Description |
|
|
415
|
+
|----------|---------------------------------------------------------|
|
|
416
|
+
| `srcset` | Value of the srcset attribute |
|
|
417
|
+
| `meta` | Runtime data returned by [fetchContent](#fetch-content) |
|
|
418
|
+
|
|
419
|
+
Usage:
|
|
420
|
+
|
|
421
|
+
```tsx
|
|
422
|
+
import {UrlProcessor} from '@enonic/nextjs-adapter';
|
|
423
|
+
|
|
424
|
+
const url = UrlProcessor.processSrcSet('<srcset value>', meta);
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
#### `static setSiteKey(key: string): void`
|
|
430
|
+
|
|
431
|
+
Sets the site key value that is needed for correct URL processing. It is automatically done by `nextjs-adapter` so you don't have to do it.
|
|
432
|
+
|
|
433
|
+
> **WARNING:** Overriding this value may result in wrong URL processing !
|
|
434
|
+
|
|
435
|
+
| Argument | Description |
|
|
436
|
+
|----------|-------------|
|
|
437
|
+
| `key` | Site key |
|
|
438
|
+
|
|
439
|
+
Usage:
|
|
440
|
+
|
|
441
|
+
```tsx
|
|
442
|
+
import {UrlProcessor} from '@enonic/nextjs-adapter';
|
|
443
|
+
|
|
444
|
+
UrlProcessor.setSiteKey('<site key>');
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
#### `static isMediaLink(ref: string, linkData: LinkData[]): boolean`
|
|
450
|
+
|
|
451
|
+
Checks if link data array contains link with provided ref. Positive result means that this is a link to Enonic XP content.
|
|
452
|
+
|
|
453
|
+
> **NOTE:** link data array is contained in response of the query generated by [richTextQuery('fieldName')](#rich-text-query)
|
|
454
|
+
|
|
455
|
+
| Argument | Description |
|
|
456
|
+
|------------|-----------------|
|
|
457
|
+
| `ref` | Link ref |
|
|
458
|
+
| `linkData` | Link data array |
|
|
459
|
+
|
|
460
|
+
Usage:
|
|
461
|
+
|
|
462
|
+
```tsx
|
|
463
|
+
import {UrlProcessor} from '@enonic/nextjs-adapter';
|
|
464
|
+
|
|
465
|
+
UrlProcessor.isMediaLink('<link ref>', linkData);
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
#### `static isContentImage(ref: string, imageData: ImageData[]): boolean`
|
|
471
|
+
|
|
472
|
+
Checks if image data array contains image with provided ref. Positive response means that this is an Enonic XP image.
|
|
473
|
+
|
|
474
|
+
> **NOTE:** image data array is contained in response of the query generated by [richTextQuery('fieldName')](#rich-text-query)
|
|
475
|
+
|
|
476
|
+
| Argument | Description |
|
|
477
|
+
|-------------|------------------|
|
|
478
|
+
| `ref` | Image ref |
|
|
479
|
+
| `imageData` | Image data array |
|
|
480
|
+
|
|
481
|
+
Usage:
|
|
482
|
+
|
|
483
|
+
```tsx
|
|
484
|
+
import {UrlProcessor} from '@enonic/nextjs-adapter';
|
|
485
|
+
|
|
486
|
+
UrlProcessor.isContentImage('<image ref>', imageData);
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### Utility functions
|
|
490
|
+
|
|
491
|
+
There is also a number of utility variables and functions available at `@enonic/nextjs-adapter`.
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
```tsx
|
|
496
|
+
IS_DEV_MODE; // True if current mode == development
|
|
497
|
+
|
|
498
|
+
APP_NAME; // Name of the app defined in .env files
|
|
499
|
+
|
|
500
|
+
APP_NAME_UNDERSCORED; // APP_NAME with underscores instead of dots
|
|
501
|
+
|
|
502
|
+
APP_NAME_DASHED; // APP_NAME with dashes instead of dots
|
|
503
|
+
|
|
504
|
+
SITE_KEY; // Site key defined in .env files
|
|
505
|
+
|
|
506
|
+
enum XP_REQUEST_TYPE {
|
|
507
|
+
COMPONENT = 'component',
|
|
508
|
+
TYPE = 'type',
|
|
509
|
+
PAGE = 'page',
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
enum RENDER_MODE {
|
|
513
|
+
INLINE = 'inline',
|
|
514
|
+
EDIT = 'edit',
|
|
515
|
+
PREVIEW = 'preview',
|
|
516
|
+
LIVE = 'live',
|
|
517
|
+
ADMIN = 'admin',
|
|
518
|
+
NEXT = 'next',
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
enum XP_COMPONENT_TYPE {
|
|
522
|
+
PART = 'part',
|
|
523
|
+
LAYOUT = 'layout',
|
|
524
|
+
TEXT = 'text',
|
|
525
|
+
FRAGMENT = 'fragment',
|
|
526
|
+
PAGE = 'page',
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Sanitizes text according to graphql naming spec http://spec.graphql.org/October2021/#sec-Names
|
|
530
|
+
const sanitizeGraphqlName = (text: string) => string;
|
|
531
|
+
|
|
532
|
+
// Returns common part of 2 strings
|
|
533
|
+
const commonChars = (s1?: string, s2?: string) => string;
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Views
|
|
537
|
+
|
|
538
|
+
They are located in `@enonic/nextjs-adapter/views` folder. Each view is a default export in the corresponding file.
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
#### `<MainView common="common" data="data" page="page" meta="meta">`
|
|
543
|
+
|
|
544
|
+
The main view of the application. It accepts the result of [fetchContent](#fetch-content) method.
|
|
545
|
+
Should be default export from your [next.js route](https://nextjs.org/docs/routing/introduction)
|
|
546
|
+
|
|
547
|
+
| Argument | Type | Description |
|
|
548
|
+
|----------|-----------------------------------|-----------------------------|
|
|
549
|
+
| `common` | `Record<string, any> | null` | Result of the common query |
|
|
550
|
+
| `data` | `Record<string, any> | null` | Result of the graphql query |
|
|
551
|
+
| `page` | `PageComponent | null` | Page structure |
|
|
552
|
+
| `meta` | `MetaData` | Runtime info |
|
|
553
|
+
|
|
554
|
+
Usage:
|
|
555
|
+
|
|
556
|
+
```tsx
|
|
557
|
+
import MainView from '@enonic/nextjs-adapter/views/MainView';
|
|
558
|
+
import fetchContent from '@enonic/nextjs-adapter';
|
|
559
|
+
|
|
560
|
+
export async function getServerSideProps(context: Context) {
|
|
561
|
+
const props = fetchContent('/content/path', context);
|
|
562
|
+
return {
|
|
563
|
+
props
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
export default MainView;
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
#### `<StaticContent condition="true" tag="div">`
|
|
573
|
+
|
|
574
|
+
Tag for disabling client side hydration if the condition is true. This will remove interactivity from children.
|
|
575
|
+
|
|
576
|
+
| Argument | Type | Description |
|
|
577
|
+
|--------------------|-----------|------------------------------------|
|
|
578
|
+
| `condition = true` | `Boolean` | Condition to trigger static output |
|
|
579
|
+
| `tag = 'div'` | `String` | Html tag to use for static output |
|
|
580
|
+
|
|
581
|
+
Usage:
|
|
582
|
+
|
|
583
|
+
```tsx
|
|
584
|
+
import StaticContent from '@enonic/nextjs-adapter/views/StaticContent';
|
|
585
|
+
|
|
586
|
+
<StaticContent condition={true} tag="div"> ...child elements... </StaticContent>
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
#### <a id="rich-text-view"></a>`<RichTextView className="css-class" tag="section" data={data} meta={meta}, renderMacroInEditMode="true", customReplacer={customReplacerFn}>`
|
|
592
|
+
|
|
593
|
+
Tag for displaying contents of html area input types. Takes care of processing macros, URLs and images inside.
|
|
594
|
+
|
|
595
|
+
| Argument | Type | Description |
|
|
596
|
+
|--------------------------------|----------------|---------------------------------------------------------------------------------------------------|
|
|
597
|
+
| `data` | `RichTextData` | Rich text data |
|
|
598
|
+
| `meta` | `MetaData` | Runtime data returned by fetchContent method. |
|
|
599
|
+
| `customReplacer` | `Replacer` | Function to do custom element processing. Not invoked for image, link and macro nodes. _Optional_ |
|
|
600
|
+
| `className` | `String` | Class name to add to the root html element. _Optional_ |
|
|
601
|
+
| `renderMacroInEditMode = true` | `boolean` | Flag passed to macros telling if they should render themselves in edit mode |
|
|
602
|
+
| `tag = 'div'` | `String` | Html tag to use as a root |
|
|
603
|
+
|
|
604
|
+
> **TIP!** There is a utility function [richTextQuery(fieldName)](#rich-text-query) generating part of the graphql query to
|
|
605
|
+
> obtain `RichTextData` for html area input types.
|
|
606
|
+
|
|
607
|
+
Usage:
|
|
608
|
+
|
|
609
|
+
```tsx
|
|
610
|
+
import RichTextView from '@enonic/nextjs-adapter/views/RichTextView';
|
|
611
|
+
|
|
612
|
+
<RichTextView data={richTextData} meta={meta} tag="section" className="rich-text-view" renderMacroInEditMode="false"></RichTextView>
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
#### `<Regions page={page} meta={meta} name="main" common={common}>`
|
|
618
|
+
|
|
619
|
+
Tag for rendering page regions. It is useful when implementing custom page views.
|
|
620
|
+
All necessary data can be acquired by running [fetchContent()](#fetch-content)
|
|
621
|
+
|
|
622
|
+
| Argument | Type | Description |
|
|
623
|
+
|----------|-------------------------|-------------------------------------|
|
|
624
|
+
| `page` | `PageData | null;` | Page structure |
|
|
625
|
+
| `meta` | `MetaData` | Runtime info |
|
|
626
|
+
| `name` | `String` | Render only this region. _Optional_ |
|
|
627
|
+
| `common` | `any` | Result of common query. _Optional_ |
|
|
628
|
+
|
|
629
|
+
Usage:
|
|
630
|
+
|
|
631
|
+
```tsx
|
|
632
|
+
import StaticContent from '@enonic/nextjs-adapter/views/StaticContent';
|
|
633
|
+
|
|
634
|
+
<StaticContent condition={true} tag="div"> ...child elements... </StaticContent>
|
|
22
635
|
```
|
|
23
636
|
|
|
24
|
-
##
|
|
637
|
+
## Known problems
|
|
638
|
+
|
|
639
|
+
---
|
|
25
640
|
|
|
26
641
|
In some cases, when using in NextJS application, a build errors related to the JSX may appear, that state the following:
|
|
27
642
|
```
|
|
28
643
|
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
|
29
644
|
```
|
|
30
|
-
|
|
31
|
-
|
|
645
|
+
To prevent these errors, it is necessary to transpile the library using something
|
|
646
|
+
like [`next-transpile-modules`](https://www.npmjs.com/package/next-transpile-modules).
|
|
32
647
|
Install it as dev dependency and call it explicitly from you NextJS config:
|
|
33
648
|
|
|
34
649
|
`next.config.js`
|
package/UrlProcessor.d.ts
CHANGED
|
@@ -15,8 +15,9 @@ export declare class UrlProcessor {
|
|
|
15
15
|
static setSiteKey(key: string): void;
|
|
16
16
|
static isMediaLink(ref: string, linkData: LinkData[]): boolean;
|
|
17
17
|
static isContentImage(ref: string, linkData: ImageData[]): boolean;
|
|
18
|
+
static processSrcSet(srcset: string, meta: MetaData): string;
|
|
18
19
|
private static stripApiUrl;
|
|
19
20
|
private static isPageUrl;
|
|
20
21
|
private static getApiUrl;
|
|
21
22
|
}
|
|
22
|
-
export declare const getUrl:
|
|
23
|
+
export declare const getUrl: (url: string, meta: MetaData) => string;
|