npm package: @jahia/nextjs-sdk
Description: The aim of the Jahia Nextjs initiative is to explore and explain the Jahia capabilities to easily create and manage headless web project. Solutions we use are : - [Jahia][jahia-website] : a Cloud / On-premise *DXP* solution to create and contribute - [Ver
Latest version: 0.0.7
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# The Jahia Nextjs initiative : *jahia SDK for Nextjs*

The aim of the Jahia Nextjs initiative is to explore and explain
the Jahia capabilities to easily create and manage headless web project.
Solutions we use are :
- [Jahia][jahia-website] : a Cloud / On-premise *DXP* solution to create and contribute
- [Vercel][vercel-website] a next-js Cloud platform provider to render the web project

To know more about the Jahia Nextjs initiative [read this dedicated page][initiative.md].

## Why this sdk ?
Use the sdk in **Nextjs** headless project:
- to create and export easily wysiwyg webpage template
- to get content properties stored in **Jahia** with one line of code in a **React** component
- to manage *edit*, *preview* and *live* urls
- and much more

## Installation
The SDK is available as an [npm package][npm-package].
To install the sdk in a project, run one of this command :
```shell
# with npm
npm install @jahia/nextjs-sdk

# with yarn
yarn add @jahia/nextjs-sdk
```
To know more about the full configuration of a project using
**Jahia** and **Nextjs** read the [setup][setup.md].

## Quick start to use the sdk in a Nextjs project
To understand in details the architecture of a **Nextjs** project using **Jahia**, have a look at the
[architecture][archi.md].

>In this section we present source code extracted from the [nextjs-industrial] project.
This project is a fully functional website using **Jahia** and **Nextjs**.

### Pages
Pages are created and managed in **Jahia**, and the page url is based on the jahia page path.
To render the page in **Nextjs** you have to create a `[[slug.js]]` file in the **pages**
folder and copy/past the following code :
```js
/* eslint-disable prefer-destructuring */
import {JahiaPage} from '@jahia/nextjs-sdk';

export default JahiaPage.Component;
export const getStaticPaths = JahiaPage.getStaticPaths;
export const getStaticProps = JahiaPage.getStaticProps;
```

To render the pages properly you have to :
- run the registration of components
- get initial main content properties

This is done in the `_app.jsx` file:

```js
import React from 'react';
import {JahiaNextApp} from '@jahia/nextjs-sdk';

/* Load css or other if needed */

import {registerComponents} from '../components/registerComponents';

registerComponents();

JahiaNextApp.useRender = () => {
    /* Do extra stuff if needed*/
};

export default JahiaNextApp;
```

The **components** folder contains for each content type templates and/or views.
For example, for the page content type `jnt:page` we register three templates (default,open and fixed Structure)
using two components `PageOpenTemplate` and `PageFixedStructureTemplate`
and the registration element :

```js
import {PageOpenTemplate, PageFixedStructureTemplate} from './Page';
export const registerComponents = () => {
    Object.assign(templates, {
        'jnt:page': {
            default: PageOpenTemplate,
            open: PageOpenTemplate,
            'fixed Structure': PageFixedStructureTemplate,
        },
        ...

    });
    ...
}
```
> Note : a special api service is used to select from the Jahia UI
> the available templates. See this [file][api-templates].

You can now start to use Jahia components or create your own.

### SDK Components
|Name|Props|Description|
|---|---|---|
|Area| `name`, `tagProps`, `componentProps`, `path` |This component enable the **in-context** contribution in the webpage. The **Area** is used by Jahia to create a slot in edit mode where a contributor can create or copy/past a content.|
|DefaultImage| `path`, `alt`, `className`, `width`, `height`  |This component is use to render an image. For the moment (alpha release) it doesn't use the Next **Image** component.|
|EmbeddedPathInHtmlResolver| `htmlAsString` |This component is to resolve anchor href or image src path embedded in an HTML string written with a RichText editor. This component replace the `dangerouslySetInnerHTML` props|
|JahiaLink| same as **Link** from Next |This component is a wrapper of the **Link** component provided by Next. The **JahiaLink** generate the appropriate link to browse the website in edit or preview mode from Jahia, or in live mode from Vercel. The live link is generated with the **Link** component provided by Next.|
|ContentReference| `id`, `referenceComponent`, `className` |This component is used to render a content used through a reference in Jahia (like a symlink in linux). You have a unique content you can use in several pages with a specific rendering. `referenceComponent` is useful if you want to force the rendering of the content in reference with a specific component|
|ImageReferenceLink| `id`, `referenceComponent`, `className` |This component is used to render the default Jahia content type: **Image (from the document manager)**. Link rendering is not implemented yet (alpha release).|
|RichText| `id` |This component is used to render the default Jahia content type: **Rich text**.|

### GraphQL helper function
The sdk exports the **useNode** function, which resumes in one line the GraphQL call needed
to get content properties.

typescript signature:
```js
const useNode = (uuid: string, properties: string[]=[], children= false)
```

#### Example of usage
Let consider a content using this content definition:
```
[hicnt:featureContentBloc]> jnt:content
  - title (string) internationalized
  - teaser (string) internationalized
  - iconName (string)
```
To retrieve the value of the properties in your React component, use the **useNode()** function
as follows:
```js
import {useNode} from '@jahia/nextjs-sdk';

function FeatureContentBloc({id}) {
    const {data, error, loading} = useNode(id, ['title', 'teaser', 'iconName']);
    ...
}
```
The function returns a **data** object with a **properties** object which contains the props, and a **children** array
which contains child nodes if children props is set to true.
```js
const {title, teaser, iconName} = data.properties;
```
The function returns also **core** properties accessible directly from the **data** object:
- `uuid`: unique id of the content
- `path`: path of the content in the content tree
- `name`: technical name of the content
- `primaryNodeType.name`: type of content
- `mixinTypes[{name}]`: name of the mixins associated to the content
- `view`: name of the component to call to render the content

>Note: you can always write your own GraphQL query and use it with the apollo useQuery function.
> Don't forget to use the CORE_NODE_FIELDS fragment for apollo cache purpose

[jahia-website]: https://www.jahia.com
[vercel-website]: https://vercel.com
[initiative.md]: https://github.com/Jahia/jahia-nextjs-initiative/blob/main/README.md
[npm-package]:https://www.npmjs.com/package/@jahia/nextjs-sdk

[env-var]: https://github.com/Jahia/jahia-nextjs-initiative/blob/main/doc/setup.md#next-industrial-webapp-configuration
[setup.md]: https://github.com/Jahia/jahia-nextjs-initiative/blob/main/doc/setup.md
[archi.md]: https://github.com/Jahia/jahia-nextjs-initiative/blob/main/doc/architecture.md
[nextjs-industrial]:https://github.com/Jahia/nextjs-industrial
[api-templates]:https://github.com/Jahia/nextjs-industrial/blob/main/pages/api/jahia/templates.js