Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Finalize 2.x Documentation #804

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
10 changes: 9 additions & 1 deletion www/config/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const docsConfig: DocsConfig = {
],
},
{
title: "Drupal Client",
title: "NextDrupal Client",
items: [
{
title: "Introduction",
Expand Down Expand Up @@ -94,6 +94,10 @@ export const docsConfig: DocsConfig = {
title: "Advanced Example",
href: "/docs/pages#advanced-example",
},
{
title: "Pages Router",
href: "/docs/pages#pages-router",
},
],
},
{
Expand Down Expand Up @@ -196,6 +200,10 @@ export const docsConfig: DocsConfig = {
title: "getAuthorizationHeader",
href: "/docs/reference/getauthorizationheader",
},
{
title: "Pages Router",
href: "/docs/reference/pages-router",
},
],
},
{
Expand Down
8 changes: 6 additions & 2 deletions www/config/site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,16 @@ export const site: SiteConfig = {
},
versions: [
{
version: "v1.6.0",
version: "v2.0.0",
active: true,
},
{
version: "v1.0.0",
version: "v1.6.0",
url: "https://v1.next-drupal.org",
},
{
version: "canary",
url: "https://next.next-drupal.org",
},
],
}
10 changes: 10 additions & 0 deletions www/content/blog/next-drupal-2-0.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: Next-Drupal 2.0
author: brianperry
date: October 31, 2024
created: "2024-10-31"
excerpt: Next.js 14, Drupal 11 and App Router Support.
published: true
---

Write this post.
20 changes: 20 additions & 0 deletions www/content/docs/client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ It also comes with full support for JSON:API write operations which means you ca

## Usage

### App Router

```ts
import { NextDrupal } from "next-drupal"

Expand All @@ -41,3 +43,21 @@ const article = await drupal.getResource(
"f4c61473-8297-4bf3-bab7-21c9633a7ca7"
)
```

### Pages Router

```ts
import { NextDrupalPages } from "next-drupal"

// Create a new DrupalClient.
const drupal = new NextDrupalPages("https://example.com")

// Fetch articles.
const articles = await drupal.getResourceCollection("node--article")

// Fetch one article by id.
const article = await drupal.getResource(
"node--article",
"f4c61473-8297-4bf3-bab7-21c9633a7ca7"
)
```
38 changes: 36 additions & 2 deletions www/content/docs/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ excerpt: Initialization and options for NextDrupal client.

## Initialization

### App Router

To create a new `NextDrupal` client, use the following initialization:

```ts
Expand All @@ -19,6 +21,22 @@ Where `NEXT_PUBLIC_DRUPAL_BASE_URL` is the URL to your Drupal site defined as an
NEXT_PUBLIC_DRUPAL_BASE_URL=http://example.com
```

### Pages Router

To create a new `NextDrupal` client, use the following initialization:

```ts
import { NextDrupaPages } from "next-drupal"

const drupal = new NextDrupalPages(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL)
```

Where `NEXT_PUBLIC_DRUPAL_BASE_URL` is the URL to your Drupal site defined as an [environment variable](/docs/environment-variables).

```txt title=.env.local
NEXT_PUBLIC_DRUPAL_BASE_URL=http://example.com
```

---

## Options
Expand Down Expand Up @@ -89,6 +107,24 @@ new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, {

You can find more info about using a custom deserializer [here](/docs/deserializer).

#### Pages Router

This option is called `serializer` in the `NextDrupalPages` client. Aside from that, the usage is the same.

```ts
import { Deserializer } from "jsonapi-serializer"

const jsonDeserializer = new Deserializer({
keyForAttribute: "camelCase",
})

const customDeserializer = jsonSerializer.deserialize.bind(jsonSerializer)

new NextDrupalPages(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, {
serializer: customDeserializer,
})
```

---

### fetcher
Expand Down Expand Up @@ -224,5 +260,3 @@ JSON:API errors are thrown in non-production environments by default. The errors
- **Required**: No

By default, the resource endpoint will be based on the resource name. If you turn this off, a JSON:API request will retrieve the resource's endpoint url.

---
24 changes: 24 additions & 0 deletions www/content/docs/deserializer.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,27 @@ export const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, {
deserializer: customDeserializer,
})
```

### Pages Router

This option is called `serializer` in the `NextDrupalPages` client. Aside from that, the usage is the same.

```ts title=lib/drupal.ts
import { NextDrupal } from "next-drupal"
import { Deserializer } from "jsonapi-serializer"

// Create a custom deserializer.
const jsonDeserializer = new Deserializer({
keyForAttribute: "camelCase",
})

const customDeserializer = jsonDeserializer.deserialize.bind(jsonDeserializer)

// Pass the custom deserializer to the client.
export const drupal = new NextDrupalPages(
process.env.NEXT_PUBLIC_DRUPAL_BASE_URL,
{
serializer: customDeserializer,
}
)
```
4 changes: 4 additions & 0 deletions www/content/docs/faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ excerpt: Frequently Asked Questions about Next.js for Drupal

Next.js for Drupal works requires Drupal 9.3+ and Drupal 10.

## Which Next.js versions are supported?

Next.js for Drupal supports both Next.js 13 and Next.js 14. This includes support for both the App Router and the Pages Router.

## Does it work without authentication?

Yes. Authentication is only required for previewing unpublished entities and revisions.
Expand Down
172 changes: 158 additions & 14 deletions www/content/docs/pages.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,10 @@ title: Building Pages
excerpt: How to build pages using JSON:API resources from Drupal.
---

In Next.js V14, data fetching has evolved significantly from previous versions. Instead of using `getStaticProps` and `getServerSideProps` you now use the native `fetch` function enhanced by Next.js to handle server-side data fetching.

The `NextDrupal` client provides several functions to help you query JSON:API resources from Drupal.

<!--
************************************************************
* TODO: Remove this block before publishing.

* Comment: Need to corroborate (and maybe update) once next-drupal supports `next` revalidation options. Possible replacement for above introduction once it's supported

In Next.js V14, data fetching has evolved significantly from previous versions. Instead of using `getStaticProps` and `getServerSideProps` you now use the native `fetch` function enhanced by Next.js to handle server-side data fetching. This allows you to configure caching and revalidation directly within your fetch requests. These can be used in Server Components, Route Handlers, and Server Actions. You can read more about it [here](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating)
In the Next.js App Router, data fetching has evolved significantly from previous versions. The native `fetch` function enhanced by Next.js can be used to handle server-side data fetching. This also allows you to configure caching and revalidation directly within your fetch requests. These can be used in Server Components, Route Handlers, and Server Actions. You can read more about it [here](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating).

The `NextDrupal` client provides several functions to help you query JSON:API resources from Drupal and manage these revalidation options on the `fetch` request level.

************************************************************
-->

---

## Basic Example
Expand Down Expand Up @@ -53,6 +40,18 @@ export default function AboutPage() {
}
```

### Time-based Revalidation

To use time-based revalidation, you can pass a `revalidate` option to the `getResource` function. This will set the cache lifetime of a resource (in seconds).

```tsx
const node = await drupal.getResource(
"node--page",
"07464e9f-9221-4a4f-b7f2-01389408e6c8",
{ next: { revalidate: 3600 } }
)
```

---

## Dynamic pages
Expand Down Expand Up @@ -156,6 +155,151 @@ export default function Page({ params }) {
}
```

### Tag-based Revalidation

In addition to revalidating based on time, it is also possible to revalidate
based on cache tag values. This is useful when you want to revalidate a resource
based on changes to other resources.

Below we've adapted the Page function from the example above to include
tag-based revalidation.

```tsx title=app/[...slug]/page.tsx
import { DrupalJsonApiParams } from "drupal-jsonapi-params"

...

export default function Page({ params }) {
const {slug} = params;

const path = drupal.translatePath(slug)

// Get the resource type.
const type = path.jsonapi.resourceName
const tag = `${path.entity.type}:${path.entity.id}`

const params = new DrupalJsonApiParams()

// Fetch the title, path and body field for pages.
if (type === "node--page") {
params.addFields("node--page", ["title", "path", "body"])
}

// Fetch additional fields for articles.
if (type === "node--article") {
params.addFields("node--article", ["title", "path", "body", "uid"])
}

const node = await drupal.getResource(path, path.entity.uuid {
params: params.getQueryObject(),
tags: [tag]
})

// Render different Components based on Node type.
if (node.type === "node--page") {
return <PageComponent node={node}/>
}

if (node.type === "node--article") {
return <ArticleComponent node={node}/>
}

return null
}
```

## Reference

See the [fetching JSON:API resources](/docs/fetching-resources) section for more examples of fetching resources and collection of resources.

## Pages Router

When using the Pages Router, you will use the `getStaticProps` and `getServerSideProps` methods to fetch data for your pages.

### Basic Example

Here's an example which uses `getResource` to fetch a `page` node by ID:

```tsx
const node = await drupal.getResource(
"node--page",
"07464e9f-9221-4a4f-b7f2-01389408e6c8"
)
```

A full page would look like this:

```tsx title=pages/about.tsx
// node will be populated at build time by getStaticProps
export default function AboutPage({ node }) {
return (
<article>
<h1>{node.title}</h1>
// ...
</article>
)
}

export async function getStaticProps() {
// Fetch the node from Drupal.
const node = await drupal.getResource(
"node--page",
"07464e9f-9221-4a4f-b7f2-01389408e6c8"
)

// Pass the node as props to the AboutPage.
return {
props: {
node,
},
}
}
```

---

## Dynamic pages

You can use Next.js [dynamic route](https://nextjs.org/docs/basic-features/pages#pages-with-dynamic-routes) to build static pages for Drupal entity types.

Start by creating a page at `/pages/[...slug].tsx`, where `[...slug]` maps to the **path alias** for an entity type (or content type) in Drupal.

This means `/pages/[...slug].tsx` will handle all pages with the following aliases: `/about`, `/team`, `/another/path` ...etc.

To build static pages, there are two functions we need to implement:

1. `getStaticPaths`: to tell Next.js all the routes that we want to be rendered.
2. `getStaticProps`: to fetch data for pages.

```tsx title=pages/[...slug].tsx
export default function Page({ node }) {
return (
<article>
<h1>{node.title}</h1>
// ...
</article>
)
}

export async function getStaticPaths(context) {
// Build paths for all `node--page`.
return {
paths: await drupal.getStaticPathsFromContext("node--page", context),
fallback: false,
}
}

export async function getStaticProps(context) {
// Fetch the node based on the context.
// next-drupal automatically handles the slug value.
const node = await drupal.getResourceFromContext("node--page", context)

return {
props: {
node,
},
}
}
```

---
9 changes: 9 additions & 0 deletions www/content/docs/reference/pages-router.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Pages Router
excerpt: An index of methods specific to the Pages Router.
---

TODO

- Link 1
- Link 2
Loading
Loading