diff --git a/www/config/docs.ts b/www/config/docs.ts index 7c4360e23..1bdbed9d7 100644 --- a/www/config/docs.ts +++ b/www/config/docs.ts @@ -49,8 +49,8 @@ export const docsConfig: DocsConfig = { href: "/docs/environment-variables", }, { - title: "Preview Mode", - href: "/docs/preview-mode", + title: "Draft Mode", + href: "/docs/draft-mode", }, { title: "TypeScript", @@ -108,8 +108,8 @@ export const docsConfig: DocsConfig = { href: "/docs/fetcher", }, { - title: "Serializer", - href: "/docs/serializer", + title: "Deserializer", + href: "/docs/deserializer", }, { title: "Caching", @@ -124,10 +124,6 @@ export const docsConfig: DocsConfig = { title: "getResource", href: "/docs/reference/getresource", }, - { - title: "getResourceFromContext", - href: "/docs/reference/getresourcefromcontext", - }, { title: "getResourceByPath", href: "/docs/reference/getresourcebypath", @@ -136,10 +132,6 @@ export const docsConfig: DocsConfig = { title: "getResourceCollection", href: "/docs/reference/getresourcecollection", }, - { - title: "getResourceCollectionFromContext", - href: "/docs/reference/getresourcecollectionfromcontext", - }, { title: "createResource", href: "/docs/reference/createresource", @@ -157,28 +149,20 @@ export const docsConfig: DocsConfig = { href: "/docs/reference/deleteresource", }, { - title: "getStaticPathsFromContext", - href: "/docs/reference/getstaticpathsfromcontext", + title: "getResourceCollectionPathSegments", + href: "/docs/reference/getresourcecollectionpathsegments", }, { title: "translatePath", href: "/docs/reference/translatepath", }, { - title: "translatePathFromContext", - href: "/docs/reference/translatepathfromcontext", - }, - { - title: "getPathFromContext", - href: "/docs/reference/getpathfromcontext", - }, - { - title: "getEntryForResourceType", - href: "/docs/reference/getentryforresourcetype", + title: "constructPathFromSegment", + href: "/docs/reference/constructpathfromsegment", }, { - title: "preview", - href: "/docs/reference/preview", + title: "buildEndpoint", + href: "/docs/reference/buildendpoint", }, { title: "getAccessToken", @@ -208,6 +192,10 @@ export const docsConfig: DocsConfig = { title: "deserialize", href: "/docs/reference/deserialize", }, + { + title: "getAuthorizationHeader", + href: "/docs/reference/getauthorizationheader", + }, ], }, { diff --git a/www/config/tutorials.ts b/www/config/tutorials.ts index 9e868286a..3046d74f9 100644 --- a/www/config/tutorials.ts +++ b/www/config/tutorials.ts @@ -12,9 +12,9 @@ export const tutorialsConfig = [ items: [], }, { - title: "Preview Mode", - excerpt: "Implement Preview Mode for Entity Types.", - url: "/learn/preview-mode", + title: "Draft Mode", + excerpt: "Implement Draft Mode for Entity Types.", + url: "/learn/draft-mode", items: [], }, { diff --git a/www/content/docs/authentication.mdx b/www/content/docs/authentication.mdx index 765ba8bb3..76b5c6f10 100644 --- a/www/content/docs/authentication.mdx +++ b/www/content/docs/authentication.mdx @@ -1,9 +1,9 @@ --- title: Authentication -excerpt: Making authenticated requests with DrupalClient. +excerpt: Making authenticated requests with NextDrupal. --- -The `DrupalClient` works with several auth types. You can use **Bearer** tokens, **Basic** tokens or bring your own authorization headers. +The `NextDrupal` client works with several auth types. You can use **Bearer** tokens, **Basic** tokens or bring your own authorization headers. Authentication can be set globally on the client or custom per method. @@ -16,9 +16,9 @@ This is the default authentication configured on the client. **This is used most of the time for fetching and building static pages.** ```ts title=lib/drupal.ts -import { DrupalClient } from "next-drupal" +import { NextDrupal } from "next-drupal" -export const drupal = new DrupalClient( +export const drupal = new NextDrupal( process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { auth: // Configure the global auth here. @@ -59,15 +59,12 @@ You need to enable the `simple_oauth` module on Drupal. ```ts title=lib/drupal.ts // Client -export const drupal = new DrupalClient( - process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, - { - auth: { - clientId: process.env.DRUPAL_CLIENT_ID, - clientSecret: process.env.DRUPAL_CLIENT_SECRET, - }, - } -) +export const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + auth: { + clientId: process.env.DRUPAL_CLIENT_ID, + clientSecret: process.env.DRUPAL_CLIENT_SECRET, + }, +}) // Method const article = drupal.getResource( @@ -82,26 +79,23 @@ const article = drupal.getResource( ) ``` -`DrupalClient` will fetch **Bearer** token and handle expiration for you. +`NextDrupal` client will fetch **Bearer** token and handle expiration for you. If you need to customize the OAuth URL you can use the `url` option. ```ts title=lib/drupal.ts -export const drupal = new DrupalClient( - process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, - { - auth: { - clientId: process.env.DRUPAL_CLIENT_ID, - clientSecret: process.env.DRUPAL_CLIENT_SECRET, - // highlight-start - url: `/oauth2/token`, - // highlight-end - }, - } -) +export const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + auth: { + clientId: process.env.DRUPAL_CLIENT_ID, + clientSecret: process.env.DRUPAL_CLIENT_SECRET, + // highlight-start + url: `/oauth2/token`, + // highlight-end + }, +}) ``` -By default, `DrupalClient` uses `/oauth/token` as the default URL. +By default, `NextDrupal` uses `/oauth/token` as the default URL. --- @@ -117,15 +111,12 @@ You need to enable the `basic_auth` module on Drupal. ```ts // Client. -export const drupal = new DrupalClient( - process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, - { - auth: { - username: process.env.DRUPAL_USERNAME, - password: process.env.DRUPAL_PASSWORD, - }, - } -) +export const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + auth: { + username: process.env.DRUPAL_USERNAME, + password: process.env.DRUPAL_PASSWORD, + }, +}) // Method const articles = await drupal.getResourceCollection("node--article", { @@ -144,14 +135,11 @@ You can also provide a custom callback for authentication. The callback must ret ```ts // Client -export const drupal = new DrupalClient( - process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, - { - auth: () => { - // Do something and return an Authorization header. - }, - } -) +export const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + auth: () => { + // Do something and return an Authorization header. + }, +}) // Method const users = await drupal.getResourceCollection("user--user", { @@ -167,16 +155,13 @@ You can also pass in an access token. ```ts // Client -export const drupal = new DrupalClient( - process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, - { - auth: { - access_token: "ECYM594IlARGc3S8KgBHvTpki0rDtWx6...", - token_type: "Bearer", - expires_in: 3600, - }, - } -) +export const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + auth: { + access_token: "ECYM594IlARGc3S8KgBHvTpki0rDtWx6...", + token_type: "Bearer", + expires_in: 3600, + }, +}) // Method const articles = await drupal.getResourceCollection("node--article", { @@ -198,7 +183,7 @@ import { getSession } from "next-auth/react" const session = getSession(...) // Client -export const drupal = new DrupalClient( +export const drupal = new NextDrupal( process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { auth: session.accessToken, diff --git a/www/content/docs/cache.mdx b/www/content/docs/cache.mdx index 93aae1cb8..9089eadde 100644 --- a/www/content/docs/cache.mdx +++ b/www/content/docs/cache.mdx @@ -3,7 +3,7 @@ title: Caching excerpt: Using a custom cache for resources. --- -The `DrupalClient` has support for caching resources. +The `NextDrupal` client has support for caching resources. This is handy when dealing with global data: you can fetch data once and re-use during builds. @@ -22,7 +22,7 @@ Note: as of `next-drupal 1.3.0`, only `getResource` and `getMenu` support cachin ```ts title=lib/drupal.ts -import { DrupalClient, DataCache } from "next-drupal" +import { NextDrupal, DataCache } from "next-drupal" import Redis from "ioredis" const redis = new Redis(process.env.REDIS_URL) @@ -37,12 +37,9 @@ export const redisCache: DataCache = { }, } -export const drupal = new DrupalClient( - process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, - { - cache: redisCache, - } -) +export const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + cache: redisCache, +}) ``` Now when you make a `getResource` or `getMenu` call you can tell the client to cache and re-use responses. diff --git a/www/content/docs/client.mdx b/www/content/docs/client.mdx index 23f3dafd0..5e6290805 100644 --- a/www/content/docs/client.mdx +++ b/www/content/docs/client.mdx @@ -1,11 +1,11 @@ --- -title: Drupal Client +title: NextDrupal Client excerpt: A powerful JSON:API client for Drupal. --- -The `DrupalClient` is a powerful JSON:API client that ships with helpers for working with Drupal data. +The `NextDrupal` client is a powerful JSON:API client that ships with helpers for working with Drupal data. -You can use the `DrupalClient` to fetch JSON:API data from Drupal to build static pages. +You can use the `NextDrupal` client to fetch JSON:API data from Drupal to build static pages in advance, or server render pages on-demand. It also comes with full support for JSON:API write operations which means you can create JSON:API resources from Next.js to Drupal. @@ -27,10 +27,10 @@ It also comes with full support for JSON:API write operations which means you ca ## Usage ```ts -import { DrupalClient } from "next-drupal" +import { NextDrupal } from "next-drupal" -// Create a new DrupalClient. -const drupal = new DrupalClient("https://example.com") +// Create a new NextDrupal client. +const drupal = new NextDrupal("https://example.com") // Fetch articles. const articles = await drupal.getResourceCollection("node--article") diff --git a/www/content/docs/configuration.mdx b/www/content/docs/configuration.mdx index e46e7cd98..3e5293afa 100644 --- a/www/content/docs/configuration.mdx +++ b/www/content/docs/configuration.mdx @@ -1,19 +1,19 @@ --- title: Configuration -excerpt: Initialization and options for DrupalClient. +excerpt: Initialization and options for NextDrupal client. --- ## Initialization -To create a new `DrupalClient`, use the following initialization: +To create a new `NextDrupal` client, use the following initialization: ```ts -import { DrupalClient } from "next-drupal" +import { NextDrupal } from "next-drupal" -const drupal = new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL) +const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL) ``` -Where `NEXT_PUBLIC_DRUPAL_BASE_URL` is the URL to your Drupal site defined as an [enviroment variable](/docs/enviroment-variables). +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 @@ -33,7 +33,7 @@ Additional options can be passed during initialization to customize the behavior The JSON:API prefix to use. If you are using the [JSON:API Extras](https://www.drupal.org/project/jsonapi_extras) module, you can customize the JSON:API prefix and set the custom value here. ```ts -new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { +new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { apiPrefix: "/api", }) ``` @@ -48,7 +48,7 @@ new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { Use this to set the path for your front page. This path will resolve to `/` on your Next.js site. ```ts -new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { +new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { frontPage: "/front", }) ``` @@ -66,26 +66,28 @@ You can find more info about using a custom auth [here](/docs/authentication). --- -### serializer +### deserializer - **Default value**: Built-in - **Required**: No -Override the default data serializer. You can use this to add your own JSON:API data deserializer. +Override the default data deserializer. You can use this to add your own JSON:API data deserializer. ```ts import { Deserializer } from "jsonapi-serializer" -const customSerializer = new Deserializer({ +const jsonDeserializer = new Deserializer({ keyForAttribute: "camelCase", }) -new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { - serializer: customSerializer, +const customDeserializer = jsonSerializer.deserialize.bind(jsonSerializer) + +new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + deserializer: customDeserializer, }) ``` -You can find more info about using a custom serializer [here](/docs/serializer). +You can find more info about using a custom deserializer [here](/docs/deserializer). --- @@ -112,7 +114,7 @@ const customFetcher = (url, options) => { }) } -new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { +new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { fetcher: customFetcher, }) ``` @@ -144,7 +146,7 @@ export const redisCache: DataCache = { }, } -new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { +new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { cache: redisCache, }) ``` @@ -171,17 +173,6 @@ Set whether the client should use authenticated requests by default. If set to ` --- -### useDefaultResourceTypeEntry - -- **Default value**: `false` -- **Required**: No - -By default, the client will make a request to JSON:API to retrieve the index. - -If your resources follow the `entity_type--bundle` naming convention, you can safely turn this off and use the default entry point from the resource name. - ---- - ### headers - **Default value**: `{ "Content-Type": "application/vnd.api+json", Accept: "application/vnd.api+json" }` @@ -190,7 +181,7 @@ If your resources follow the `entity_type--bundle` naming convention, you can sa Set custom headers for the fetcher. ```ts -new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { +new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { headers: { "Content-Type": "application/json", }, @@ -217,3 +208,21 @@ Use this to turn on the built-in logger. If you would like to replace with your . --- + +### throwJsonApiErrors + +- **Default value**: `true` +- **Required**: No + +JSON:API errors are thrown in non-production environments by default. The errors are shown in the Next.js overlay. Use this to turn it off. + +--- + +### useDefaultEndpoint + +- **Default value**: `true` +- **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. + +--- diff --git a/www/content/docs/creating-resources.mdx b/www/content/docs/creating-resources.mdx index 3c4c3f887..d3e56379c 100644 --- a/www/content/docs/creating-resources.mdx +++ b/www/content/docs/creating-resources.mdx @@ -1,6 +1,6 @@ --- title: Creating Resources (POST) -excerpt: How to create JSON:API resources using DrupalClient. +excerpt: How to create JSON:API resources using NextDrupal client. --- @@ -9,13 +9,23 @@ The `createResource` and `createFileResource` helpers are available in `next-dru -The `DrupalClient` ships with a `createResource` and a `createFileResource` methods for creating JSON:API resources. + + +If you're working with JSON:API, be mindful to select the option: + +`Accept all JSON:API create, read, update, and delete operations.` + +on the following path: `/admin/config/services/jsonapi` in Drupal. + + + +The `NextDrupal` client ships with `createResource` and `createFileResource` methods for creating JSON:API resources. --- ## createResource -### Create Resource +#### Create Resource Create an article with a title and a body. @@ -33,7 +43,7 @@ const article = await drupal.createResource("node--article", { }) ``` -### Create Resource with Relationships +#### Create Resource with Relationships Create an article with a media field. diff --git a/www/content/docs/deleting-resources.mdx b/www/content/docs/deleting-resources.mdx index 75db53d86..473180f52 100644 --- a/www/content/docs/deleting-resources.mdx +++ b/www/content/docs/deleting-resources.mdx @@ -1,6 +1,6 @@ --- title: Deleting Resources (DELETE) -excerpt: How to delete JSON:API resources using DrupalClient. +excerpt: How to delete JSON:API resources using NextDrupal. --- @@ -9,7 +9,17 @@ The `deleteResource` helper is available in `next-drupal ^1.4.0`. -The `DrupalClient` ships with a `deleteResource` method for deleting JSON:API resources. + + +If you're working with JSON:API, be mindful to select the option: + +`Accept all JSON:API create, read, update, and delete operations.` + +on the following path: `/admin/config/services/jsonapi` in Drupal. + + + +The `NextDrupal` client ships with a `deleteResource` method for deleting JSON:API resources. --- diff --git a/www/content/docs/deserializer.mdx b/www/content/docs/deserializer.mdx new file mode 100644 index 000000000..50a81197b --- /dev/null +++ b/www/content/docs/deserializer.mdx @@ -0,0 +1,31 @@ +--- +title: Deserializer +excerpt: Using a custom deserializer with NextDrupal. +--- + +The `NextDrupal` uses [jsona](https://github.com/olosegres/jsona) as the default deserializer for serializing and deserializing JSON:API data. + +You can provide your own using the [`deserializer`](/docs/client/configuration#deserializer) option. + +--- + +## Example + +Here's how you can replace the default deserializer with [jsonapi-serializer](https://github.com/SeyZ/jsonapi-serializer). + +```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 NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + deserializer: customDeserializer, +}) +``` diff --git a/www/content/docs/draft-mode.mdx b/www/content/docs/draft-mode.mdx new file mode 100644 index 000000000..8e6215ecb --- /dev/null +++ b/www/content/docs/draft-mode.mdx @@ -0,0 +1,29 @@ +--- +title: Draft Mode +excerpt: Using draft mode with NextDrupal client. +--- + +To implement draft mode, configure entity types on Drupal. See the guide [here](/learn/draft-mode). + +1. Implement `/app/api/draft/route.ts`. + +```ts title=app/api/draft/route.ts +import { drupal } from "@/lib/drupal" +import { enableDraftMode } from "next-drupal/draft" +import type { NextRequest } from "next/server" + +export async function GET(request: NextRequest): Promise { + return enableDraftMode(request, drupal) +} +``` + +2. Implement `/app/api/disable-draft/route.ts` + +```ts title=app/api/disable-draft/route.ts +import { disableDraftMode } from "next-drupal/draft" +import type { NextRequest } from "next/server" + +export async function GET(request: NextRequest) { + return disableDraftMode() +} +``` diff --git a/www/content/docs/environment-variables.mdx b/www/content/docs/environment-variables.mdx index 62e9e45bd..7799a2932 100644 --- a/www/content/docs/environment-variables.mdx +++ b/www/content/docs/environment-variables.mdx @@ -28,7 +28,7 @@ DRUPAL_FRONT_PAGE= ## Required -These environment variables are required for initializing a new `DrupalClient`. +These environment variables are required for initializing a new `NextDrupal` client. | Name | Description | | ----------------------------- | :------------------------------------------------------------------------------------------------------------------------- | @@ -36,7 +36,7 @@ These environment variables are required for initializing a new `DrupalClient`. | `NEXT_IMAGE_DOMAIN` | The domain name for [next/image](https://nextjs.org/docs/basic-features/image-optimization#domains). Example: `drupal.org` | ```ts -const drupal = new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL) +const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL) ``` --- @@ -49,15 +49,18 @@ Environment variables required for on-demand revalidation. | -------------------------- | :------------------------------------------------------------------------------------------------ | | `DRUPAL_REVALIDATE_SECRET` | The secret for [on-demand revalidation](/docs/on-demand-revalidation). Example: `U2Y5bbkKJ08Ua8F` | -```ts title=pages/api/revalidate.ts -export default async function handler(request, response) { - const secret = request.query.secret as string +```ts title=app/api/revalidate/route.ts +async function handler(request: NextRequest) { + const searchParams = request.nextUrl.searchParams + const secret = searchParams.get("secret") // Validate secret. if (secret !== process.env.DRUPAL_REVALIDATE_SECRET) { - return response.status(401).json({ message: "Invalid secret." }) + return new Response("Invalid secret.", { status: 401 }) } } + +export { handler as GET, handler as POST } ``` --- @@ -70,7 +73,7 @@ export default async function handler(request, response) { | `DRUPAL_CLIENT_SECRET` | The OAuth client secret. Example: `3#9h$2DU#8qKb6&` | ```ts -const drupal = new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { +const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { auth: { clientId: process.env.DRUPAL_CLIENT_ID, clientSecret: process.env.DRUPAL_CLIENT_SECRET, @@ -88,7 +91,7 @@ const drupal = new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { | `DRUPAL_PASSWORD` | The Drupal password. Example: `password` | ```ts -const drupal = new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { +const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { auth: { username: process.env.DRUPAL_USERNAME, password: process.env.DRUPAL_PASSWORD, @@ -121,7 +124,7 @@ const nodes = await drupal.getResourceCollection( ``` ```ts title=DRUPAL_FRONT_PAGE -const drupal = new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { +const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { frontPage: process.env.DRUPAL_FRONT_PAGE, }) ``` diff --git a/www/content/docs/fetcher.mdx b/www/content/docs/fetcher.mdx index ba5d9f940..99cc4ffb4 100644 --- a/www/content/docs/fetcher.mdx +++ b/www/content/docs/fetcher.mdx @@ -1,9 +1,17 @@ --- title: Fetcher -excerpt: Using a custom fetcher with DrupalClient. +excerpt: Using a custom fetcher with NextDrupal. --- -The `DrupalClient` uses the polyfilled `fetch` from Next.js as the default fetcher. + + +The `NextDrupal` uses the polyfilled `fetch` from Next.js as the default fetcher. You can provide your own using the [`fetcher`](/docs/configuration#fetcher) option. @@ -20,7 +28,7 @@ We're using **cross-fetch** instead of **node-fetch** because it is compatible w ```ts title=lib/drupal.ts -import { DrupalClient } from "next-drupal" +import { NextDrupal } from "next-drupal" import crossFetch from "cross-fetch" // Create a custom fetcher. @@ -39,10 +47,7 @@ const customFetcher = (url, options) => { } // Pass the custom fetcher to the client. -export const drupal = new DrupalClient( - process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, - { - fetcher: customFetcher, - } -) +export const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + fetcher: customFetcher, +}) ``` diff --git a/www/content/docs/fetching-resources.mdx b/www/content/docs/fetching-resources.mdx index db72cc0fd..70cd6bb19 100644 --- a/www/content/docs/fetching-resources.mdx +++ b/www/content/docs/fetching-resources.mdx @@ -1,9 +1,9 @@ --- title: Fetching Resources (GET) -excerpt: How to fetch JSON:API resources using DrupalClient. +excerpt: How to fetch JSON:API resources using NextDrupal client. --- -The `DrupalClient` ships with helpers to fetch JSON:API data from Drupal. +The `NextDrupal` client ships with helpers to fetch JSON:API data from Drupal. You can fetch a single resource, `getResource` or a collection of resources, `getResourceCollection`. @@ -59,17 +59,15 @@ See the API reference for [getResource](/docs/reference/getresource). --- -## getResourceFromContext +## getResourceByPath -Fetch an article in `getStaticProps/getServerSideProps` with context. - -If you're using [internationalization](https://nextjs.org/docs/advanced-features/i18n-routing), this will automatically fetch the localized resource using the `locale` set in context. +Fetch an article by path. ```ts -const article = await drupal.getResourceFromContext("node--article", context) +const article = await drupal.getResourceByPath("/blog/slug-for-article") ``` -See the API reference for [getResourceFromContext](/docs/reference/getresourcefromcontext). +See the API reference for [getResourceByPath](/docs/reference/getresourcebypath). --- @@ -96,23 +94,6 @@ See the API reference for [getResourceCollection](/docs/reference/getresourcecol --- -## getResourceCollectionFromContext - -Fetch articles in `getStaticProps/getServerSideProps` with context. - -If you're using [internationalization](https://nextjs.org/docs/advanced-features/i18n-routing), this will automatically fetch localized resources using the `locale` set in context. - -```ts -const articles = await drupal.getResourceCollectionFromContext( - "node--article", - context -) -``` - -See the API reference for [getResourceCollectionFromContext](/docs/reference/getresourcecollectionfromcontext). - ---- - ## getMenu @@ -187,7 +168,3 @@ const article = await drupal.getResourceCollection( // highlight-end ) ``` - -## More - -See the [Examples](/examples) section for data fetching examples. diff --git a/www/content/docs/index.mdx b/www/content/docs/index.mdx index f7348c1e4..85ce2b7e1 100644 --- a/www/content/docs/index.mdx +++ b/www/content/docs/index.mdx @@ -5,7 +5,15 @@ excerpt: Next-generation front end for your Drupal site. Welcome to the next-drupal documentation. -This documentation covers `next-drupal 1.3+`. +This documentation covers `next-drupal 2.0`. + + If you're using an older version, you can find the documentation [here](https://v1.next-drupal.org). @@ -31,7 +39,7 @@ npx create-next-app -e https://github.com/chapter-three/next-drupal-basic-starte - DrupalClient + NextDrupal

A powerful JSON:API client for Drupal.

@@ -47,6 +55,6 @@ npx create-next-app -e https://github.com/chapter-three/next-drupal-basic-starte API Reference -

API Reference for DrupalClient.

+

API Reference for NextDrupal client.

diff --git a/www/content/docs/pages.mdx b/www/content/docs/pages.mdx index b008da721..2102032cd 100644 --- a/www/content/docs/pages.mdx +++ b/www/content/docs/pages.mdx @@ -3,9 +3,22 @@ title: Building Pages excerpt: How to build pages using JSON:API resources from Drupal. --- -In Next.js, you fetch server-side data in either `getStaticProps` or `getServerSideProps`. Data is then fed to your pages for pre-rendering. +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 `DrupalClient` provides several functions to help you query JSON:API resources from Drupal. +The `NextDrupal` client provides several functions to help you query JSON:API resources from Drupal. + + --- @@ -22,30 +35,21 @@ const node = await drupal.getResource( 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 ( -
-

{node.title}

- // ... -
- ) -} - -export async function getStaticProps() { +```tsx title=app/about/page.tsx +// page will be generated at build time +export default function AboutPage() { // 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, - }, - } + return ( +
+

{node.title}

+ // ... +
+ ) } ``` @@ -53,19 +57,34 @@ export async function getStaticProps() { ## 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. +You can use Next.js [dynamic routes](https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes) to build static pages for Drupal entity types. + +Start by creating a page at `/app/[...slug]/page.tsx`, where `[...slug]` maps to the **path alias** for an entity type (or content type) in Drupal. + +This means `/app/[...slug]/page.tsx` will handle all pages with the following aliases: `/about`, `/team`, `/another/path` ...etc. + +To build static pages, there is a built-in function we need to use: + +`generateStaticParams`: to tell Next.js all the routes that we want to have pre-rendered at build time. -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. +```tsx title=app/[...slug]/page.tsx -This means `/pages/[...slug].tsx` will handle all pages with the following aliases: `/about`, `/team`, `/another/path` ...etc. +export async function generateStaticParams() { + // Build paths for all `node--page`. + const resources = await drupal.getResourceCollectionPathSegments( + "node--page" + ); + return resources.map((resource) => slug: resource.segments); +} +export default function Page({ params }) { + const {slug} = params; -To build static pages, there are two functions we need to implement: + // Construct drupal path based on params + const drupalPath = drupal.constructPathFromSegment(slug) -1. `getStaticPaths`: to tell Next.js all the routes that we want to be rendered. -2. `getStaticProps`: to fetch data for pages. + // Fetch the node based on drupal path. + const node = drupal.getResourceByPath(drupalPath) -```tsx title=pages/[...slug].tsx -export default function Page({ node }) { return (

{node.title}

@@ -73,85 +92,37 @@ export default function Page({ node }) {
) } - -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, - }, - } -} ``` --- ## Advanced Example -In the example above, we used `pages/[...slug].tsx` to build static pages for `node--page`. +In the example above, we used `app/[...slug]/page.tsx` to build static pages for `node--page`. We can go a step further and handle all node types (or any entity types) in one page. -To do that, we're going to use `translatePathFromContext` which returns info about the resource type based on `slug` value in `context`. - -```tsx -export async function getStaticProps(context) { - const path = await drupal.translatePathFromContext(context) - - // Get the resource type. - const type = path.jsonapi.resourceName - - if (type === "node--article") { - // Build custom JSON:API query for article. - } - - if (type === "node--page") { - // Build custom JSON:API query for page. - } -} -``` +To do that, we're going to use `translatePath` which returns info about the resource type based on `slug` value in `params`. -Let's update `pages/[...slug].tsx` to handle both `node--page` and `node--article`. +Let's update `app/[...slug]/page.tsx` to handle both `node--page` and `node--article`. -```tsx title=pages/[...slug].tsx +```tsx title=app/[...slug]/page.tsx import { DrupalJsonApiParams } from "drupal-jsonapi-params" -export default function Page({ node }) { - if (node.type === "node--page") { - return - } - - if (node.type === "node--article") { - return - } +export async function generateStaticParams() { + // Build paths for all `node--page` and `node--article`. - return null + const resources = await drupal.getResourceCollectionPathSegments( + ["node--page", "node--article"] + ); + return resources.map((resource) => slug: resource.segments); } -export async function getStaticPaths(context) { - // Build paths for all `node--page` and `node--article`. - return { - paths: await drupal.getStaticPathsFromContext( - ["node--page", "node--article"], - context - ), - fallback: false, - } -} -export async function getStaticProps(context) { - const path = await drupal.translatePathFromContext(context) +export default function Page({ params }) { + const {slug} = params; + + const path = drupal.translatePath(slug) // Get the resource type. const type = path.jsonapi.resourceName @@ -168,15 +139,20 @@ export async function getStaticProps(context) { params.addFields("node--article", ["title", "path", "body", "uid"]) } - const node = await drupal.getResourceFromContext(type, context, { + const node = await drupal.getResource(path, path.entity.uuid { params: params.getQueryObject(), }) - return { - props: { - node, - }, + // Render different Components based on Node type. + if (node.type === "node--page") { + return + } + + if (node.type === "node--article") { + return } + + return null } ``` diff --git a/www/content/docs/preview-mode.mdx b/www/content/docs/preview-mode.mdx deleted file mode 100644 index 46f3d021b..000000000 --- a/www/content/docs/preview-mode.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Preview Mode -excerpt: Using preview mode with DrupalClient. ---- - -To implement preview mode, configure entity types on Drupal. See the guide [here](/learn/preview-mode). - -1. Implement `/pages/api/preview.ts`. - -```ts title=pages/api/preview.ts -import { drupal } from "lib/drupal" - -export default async function handler(req, res) { - return await drupal.preview(req, res) -} -``` - -2. Implement `/pages/api/exit-preview.ts` - -```ts title=pages/api/exit-preview.ts -export default function exit(_, res) { - res.clearPreviewData() - res.writeHead(307, { Location: "/" }) - res.end() -} -``` diff --git a/www/content/docs/reference/buildendpoint.mdx b/www/content/docs/reference/buildendpoint.mdx new file mode 100644 index 000000000..bf051289c --- /dev/null +++ b/www/content/docs/reference/buildendpoint.mdx @@ -0,0 +1,70 @@ +--- +title: buildEndpoint +excerpt: Get the JSON:API entry for a resource type. +--- + +```ts +const url = await drupal.buildEndpoint({ + locale, + resourceType, + path, + searchParams +}): Promise +``` + +- `type: string` + - Optional + - The resource type. Example: `node--article`. +- `locale: string` + - Optional + - The locale to fetch the index. Example: `es` or `fr`. +- `path: string` + - Optional + - The path to fetch. Example: `test`. +- `searchParams: string | Record | URLSearchParams | JsonApiParams` + - Optional + - Search params. Example: `{ bar: "baz" }`. + +--- + +## Notes + +By default, when retrieving resources in `getResource` or `getResourceCollection`, the `NextDrupal` client make a request to Drupal to fetch the JSON:API resource entry. + +Example: if you provide `node--article`, `NextDrupal` will make a request to `http://example.com/jsonapi/node/article`. + +If you would like to infer the entry from the resource type, use the [`useDefaultResourceTypeEntry`](/docs/configuration#usedefaultresourcetypeentry) option. + +```ts +const drupal = new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + useDefaultResourceTypeEntry: true, +}) +``` + +--- + +## Examples + +```ts +// https://example.com/jsonapi/node/article. +const url = await drupal.buildEndpoint({ resourceType: `node--article` }) + +// https://example.com/jsonapi/en/node/article. +const url = await drupal.buildEndpoint({ + locale: `en`, + resourceType: `node--article`, +}) + +// https://example.com/jsonapi/en/node/article?include=field_image. +const url = await drupal.buildEndpoint({ + locale: `en`, + resourceType: `node--article`, + searchParams: `include=field_image`, +}) + +// https://example.com/jsonapi/en/views/articles/page_1. +const url = await drupal.buildEndpoint({ + locale: `en`, + path: `/views/articles/page_1`, +}) +``` diff --git a/www/content/docs/reference/buildurl.mdx b/www/content/docs/reference/buildurl.mdx index 672c2c075..18d5a5983 100644 --- a/www/content/docs/reference/buildurl.mdx +++ b/www/content/docs/reference/buildurl.mdx @@ -4,13 +4,13 @@ excerpt: A helper for building Url with query params. --- ```ts -const url = drupal.buildUrl(path, params?): URL +const url = drupal.buildUrl(path, searchParams?): URL ``` - `path: string` - **Required** - The path for the url. Example: "/example" -- `params: string | Record | URLSearchParams | JsonApiParams` +- `searchParams: string | Record | URLSearchParams | JsonApiParams` - Optional --- diff --git a/www/content/docs/reference/constructpathfromsegment.mdx b/www/content/docs/reference/constructpathfromsegment.mdx new file mode 100644 index 000000000..b744484d3 --- /dev/null +++ b/www/content/docs/reference/constructpathfromsegment.mdx @@ -0,0 +1,79 @@ +--- +title: constructPathFromSegment +excerpt: Returns a Drupal path given an array of Next.js path segments, path prefix and locale. +--- + +```ts +const slug = drupal.constructPathFromSegment( + segment, + options?: { + pathPrefix, + locale, + defaultLocale + } +): string +``` + +- `segment: string | string[]` +- `options` + - Optional + - `pathPrefix: string`: Set the pathPrefix if you're calling from a subdir. Example: for `/articles/[...slug].tsx`, use `pathPrefix: "/articles"`. + - `locale: string`: The locale to fetch the resource in. + - `defaultLocale: string`: The default locale of the site. + +--- + +## Examples + +- Get the path (slug) from `en/news/article-1`. + +```ts + +const path = drupal.constructPathFromSegment('article-1', { + locale: 'en', + pathPrefix: '/news' +}) + +`path` will result in: `/en/news/article-1` + +``` + +This might be useful when trying to get the full path of the `params` object coming from `generateStaticParams`. +Ex: `app/[lang]/[...slug]/page.tsx` + +```tsx +export async function generateStaticParams() { + const apiParams = new DrupalJsonApiParams() + const params = apiParams + .addFields("node--landing_page", ["status", "path", "changed"]) + .addSort("changed", "DESC") + .addFilter("status", "1") + + const paths = await drupalClient.getResourceCollectionPathSegments( + ["node--landing_page"], + { + params: params.getQueryObject(), + defaultLocale: "en", + locales: ["en", "es"], + } + ) + + return paths.map((path) => { + return { + slug: path.segments, + lang: path.locale, + } + }) +} + +export default async function LandingPage({ params }) { + const { slug, lang } = params + + const path = drupal.constructPathFromSegment(slug, { locale: lang }) + + // If slug = ['segment-1', 'segment-2'] and lang = 'en' + // path will result in '/en/segment-1/segment-2' + + // ... +} +``` diff --git a/www/content/docs/reference/createfileresource.mdx b/www/content/docs/reference/createfileresource.mdx index 9a5ef598e..f321df656 100644 --- a/www/content/docs/reference/createfileresource.mdx +++ b/www/content/docs/reference/createfileresource.mdx @@ -28,7 +28,7 @@ const resource = await drupal.createFileResource( - `options` - Optional - `params: JsonApiParams`: JSON:API params such as `filter`, `fields`, `include` or `sort`. - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. - `deserialize: boolean`: Set to false to return the raw JSON:API response. diff --git a/www/content/docs/reference/createresource.mdx b/www/content/docs/reference/createresource.mdx index 88f93c867..49cfd475a 100644 --- a/www/content/docs/reference/createresource.mdx +++ b/www/content/docs/reference/createresource.mdx @@ -33,7 +33,7 @@ const resource = await drupal.createResource( - `options` - Optional - `params: JsonApiParams`: JSON:API params such as `filter`, `fields`, `include` or `sort`. - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. - `deserialize: boolean`: Set to false to return the raw JSON:API response. diff --git a/www/content/docs/reference/deleteresource.mdx b/www/content/docs/reference/deleteresource.mdx index 8cc4ff2be..22520bda9 100644 --- a/www/content/docs/reference/deleteresource.mdx +++ b/www/content/docs/reference/deleteresource.mdx @@ -21,7 +21,7 @@ const deleted = await drupal.deleteResource( - The resource id. Example `a50ffee7-ba94-46c9-9705-f9f8f440db94`. - `options` - Optional - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. diff --git a/www/content/docs/reference/deserialize.mdx b/www/content/docs/reference/deserialize.mdx index a4a027947..5613f4e48 100644 --- a/www/content/docs/reference/deserialize.mdx +++ b/www/content/docs/reference/deserialize.mdx @@ -7,10 +7,10 @@ excerpt: A helper for deserializing JSON:API resources. const resource = drupal.deserialize(body, options?) ``` -- `body: JsonApiResponse` +- `body` - **Required** - The raw JSON:API response. -- `body` +- `options` - Optional - Options for the deserializer. @@ -18,7 +18,7 @@ const resource = drupal.deserialize(body, options?) ## Notes -- To provide your own custom deserializer, see the [serializer docs](/docs/serializer). +- To provide your own custom deserializer, see the [deserializer docs](/docs/deserializer). --- diff --git a/www/content/docs/reference/fetch.mdx b/www/content/docs/reference/fetch.mdx index 924b9fe63..ae73e567b 100644 --- a/www/content/docs/reference/fetch.mdx +++ b/www/content/docs/reference/fetch.mdx @@ -15,6 +15,19 @@ const response = await drupal.fetch(input, init?): Promise - The fetch options with `withAuth`. - If `withAuth` is set, `fetch` will fetch an `Authorization` header before making the request. + + --- ## Notes diff --git a/www/content/docs/reference/getaccesstoken.mdx b/www/content/docs/reference/getaccesstoken.mdx index b63f81485..8e7773a12 100644 --- a/www/content/docs/reference/getaccesstoken.mdx +++ b/www/content/docs/reference/getaccesstoken.mdx @@ -4,19 +4,21 @@ excerpt: Retrieve an access token. --- ```ts -const token = await drupal.getAccessToken(options?: { +const token = await drupal.getAccessToken(clientIdSecret?: { clientId, clientSecret, - url? + url?, + scope? }): Promise ``` -- `options` +- `clientIdSecret` - Optional - - If options is not provided, `DrupalClient` will use the `clientId` and `clientSecret` configured in `auth`. + - If `clientIdSecret` is not provided, `NextDrupal` will use the `clientId` and `clientSecret` configured in `auth`. - `clientId: string`: The oauth client id. - `clientSecret: string`: The oauth client secret. - `url: string`: The oauth url. Default: `/oauth/token`. + - `scope: string` --- diff --git a/www/content/docs/reference/getauthorizationheader.mdx b/www/content/docs/reference/getauthorizationheader.mdx new file mode 100644 index 000000000..a776e06d1 --- /dev/null +++ b/www/content/docs/reference/getauthorizationheader.mdx @@ -0,0 +1,31 @@ +--- +title: getAuthorizationHeader +excerpt: Returns an authorization header based on an authentication method. +--- + +```ts +const paths = await drupal.getAuthorizationHeader( + auth +): Promise +``` + +- `auth: NextDrupalAuth` + - **Required** + - A supported authentication method. See [auth](/docs/authentication) + +--- + +## Examples + +- Auth method: `Bearer`. For this, you need a `clientId` and `clientSecret` + +```ts +const auth = { + clientId: process.env.DRUPAL_CLIENT_ID, + clientSecret: process.env.DRUPAL_CLIENT_SECRET, +} + +const authorizationHeader = await drupal.getAuthorizationHeader(auth) + +// authorizationHeader = Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjM ......... +``` diff --git a/www/content/docs/reference/getentryforresourcetype.mdx b/www/content/docs/reference/getentryforresourcetype.mdx index 25ac6248a..b9110c0fa 100644 --- a/www/content/docs/reference/getentryforresourcetype.mdx +++ b/www/content/docs/reference/getentryforresourcetype.mdx @@ -18,14 +18,14 @@ const url = await drupal.getEntryForResourceType(type, locale?): Promise ## Notes -By default, when retrieving resources in `getResource` or `getResourceCollection`, the `DrupalClient` make a request to Drupal to fetch the JSON:API resource entry.. +By default, when retrieving resources in `getResource` or `getResourceCollection`, the `NextDrupalPages` make a request to Drupal to fetch the JSON:API resource entry.. -Example: if you provide `node--article`, `DrupalClient` will make a request to `http://example.com/jsonapi/node/article`. +Example: if you provide `node--article`, `NextDrupalPages` will make a request to `http://example.com/jsonapi/node/article`. If you would like to infer the entry from the resource type, use the [`useDefaultResourceTypeEntry`](/docs/configuration#usedefaultresourcetypeentry) option. ```ts -const drupal = new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { +const drupal = new NextDrupalPages(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { useDefaultResourceTypeEntry: true, }) ``` diff --git a/www/content/docs/reference/getmenu.mdx b/www/content/docs/reference/getmenu.mdx index d598914e1..521347953 100644 --- a/www/content/docs/reference/getmenu.mdx +++ b/www/content/docs/reference/getmenu.mdx @@ -10,15 +10,16 @@ You need to install the [JSON:API Menu Items](https://www.drupal.org/project/jso
```ts -const resource = await drupal.getResource( - name, +const resource = await drupal.getMenu( + menuName, options?: { params, withAuth, deserialize, locale, defaultLocale, - withCache + withCache, + cacheKey, } ): Promise<{ items: T[] @@ -26,13 +27,13 @@ const resource = await drupal.getResource( }> ``` -- `name: string` +- `menuName: string` - **Required** - The name of the menu. Example: `main` or `footer`. - `options` - Optional - `params: JsonApiParams`: JSON:API params such as `filter`, `fields`, `include` or `sort`. - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. - `deserialize: boolean`: Set to false to return the raw JSON:API response. @@ -46,8 +47,8 @@ const resource = await drupal.getResource( ## Notes - `getMenu` returns: - - `items`: An array of `DrupalMenuLinkContent`. - - `tree`: An array of `DrupalMenuLinkContent` with children nested to match the hierarchy from Drupal. + - `items`: An array of `DrupalMenuItem`. + - `tree`: An array of `DrupalMenuItem` with children nested to match the hierarchy from Drupal. --- @@ -67,3 +68,18 @@ const menu = await drupal.getMenu("main", { cacheKey: "menu--main", }) ``` + + diff --git a/www/content/docs/reference/getresource.mdx b/www/content/docs/reference/getresource.mdx index 5d6a8a4be..edc0d1da4 100644 --- a/www/content/docs/reference/getresource.mdx +++ b/www/content/docs/reference/getresource.mdx @@ -27,7 +27,7 @@ const resource = await drupal.getResource( - `options` - Optional - `params: JsonApiParams`: JSON:API params such as `filter`, `fields`, `include` or `sort`. - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. - `deserialize: boolean`: Set to false to return the raw JSON:API response. @@ -79,12 +79,39 @@ const { data, meta, links } = await drupal.getResource( ```ts const id = "07464e9f-9221-4a4f-b7f2-01389408e6c8" -const menu = await drupal.getResource("node--article", id, { +const article = await drupal.getResource("node--article", id, { withCache: true, cacheKey: `node--article:${id}`, }) ``` + + --- ## TypeScript diff --git a/www/content/docs/reference/getresourcebypath.mdx b/www/content/docs/reference/getresourcebypath.mdx index e94fe2a82..828033d9a 100644 --- a/www/content/docs/reference/getresourcebypath.mdx +++ b/www/content/docs/reference/getresourcebypath.mdx @@ -23,7 +23,7 @@ const resource = await drupal.getResourceByPath( - `options` - Optional - `params: JsonApiParams`: JSON:API params such as `filter`, `fields`, `include` or `sort`. - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. - `deserialize: boolean`: Set to false to return the raw JSON:API response. @@ -58,6 +58,38 @@ const { data, meta, links } = await drupal.getResourceByPath( ) ``` +- Get the `es` translation for a page. + +```ts +const node = await drupal.getResourceByPath("/blog/slug-for-article", { + locale: "es", + defaultLocale: "en", +}) +``` + + + --- ## TypeScript diff --git a/www/content/docs/reference/getresourcecollection.mdx b/www/content/docs/reference/getresourcecollection.mdx index 99290e165..a73f557ad 100644 --- a/www/content/docs/reference/getresourcecollection.mdx +++ b/www/content/docs/reference/getresourcecollection.mdx @@ -57,6 +57,29 @@ const { data, meta, links } = await drupal.getResourceCollection("node--page", { }) ``` + + --- ## TypeScript diff --git a/www/content/docs/reference/getresourcecollectionfromcontext.mdx b/www/content/docs/reference/getresourcecollectionfromcontext.mdx index 4a0714316..da579209c 100644 --- a/www/content/docs/reference/getresourcecollectionfromcontext.mdx +++ b/www/content/docs/reference/getresourcecollectionfromcontext.mdx @@ -26,7 +26,7 @@ const resource = await drupal.getResourceCollectionFromContext +``` + +- `types: string | string[]` + - **Required** + - The resource types. Example: `node--article` or `["taxonomy_term--tags", "user--user"]`. +- `options` + - Optional + - `params: JsonApiParams`: JSON:API params such as `filter`, `fields`, `include` or `sort`. + - `withAuth: boolean | NextDrupalAuth`: + - Set the authentication method to use. See the [authentication docs](/docs/authentication). + - Set to `true` to use the authentication method configured on the client. + - `pathPrefix: string`: Set the pathPrefix if you're calling from a subdir. Example: for `/articles/[...slug].tsx`, use `pathPrefix: "/articles"`. + - `locale: string`: The locale to fetch the resource in. + - `defaultLocale: string`: The default locale of the site. + +--- + +## Examples + +- When used in `app/[...slug]/page.tsx` the `[...slug]` Dynamic Segment indicates that + `generateStaticParams()` is expected to return an array of objects with a `slug` property + containing an array of strings. + +```ts +export async function generateStaticParams(): Promise { + const resources = await drupal.getResourceCollectionPathSegments([ + "node--page", + "node--article", + ]) + + return resources.map((resource) => { + return { + slug: resource.segments, + } + }) +} +``` + +- When used in `app/[slug]/blog/[category]/[...slug]/page.tsx` file, `generateStaticParams()` + is expected to return an array of objects with a `lang` string, a `category` string and a `slug` array of strings. + +````ts +export async function generateStaticParams(): Promise { + const resources = await drupal.getResourceCollectionPathSegments( + ["node--article"], + { + // The pathPrefix will be removed from the returned path segments array. + pathPrefix: "/blog", + // The list of locales to return. + locales: ["en", "es"], + // The default locale. + defaultLocale: "en", + } + ); + + return resources.map((resource) => { + // NOTE: Because `pathPrefix` was set to "/blog", + // "blog" will not be included in the segments array. + + // Grab the first item from the segments array to get + // the needed "category" param. + const category = resource.segments.unshift(); + + return { + lang: resource.locale, + category, + slug: resource.segments, + }; + }) +}``` +```` diff --git a/www/content/docs/reference/getresourcefromcontext.mdx b/www/content/docs/reference/getresourcefromcontext.mdx index 347616a71..f317f7016 100644 --- a/www/content/docs/reference/getresourcefromcontext.mdx +++ b/www/content/docs/reference/getresourcefromcontext.mdx @@ -28,7 +28,7 @@ const resource = await drupal.getResourceFromContext( - `options` - Optional - `params: JsonApiParams`: JSON:API params such as `filter`, `fields`, `include` or `sort`. - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. - `deserialize: boolean`: Set to false to return the raw JSON:API response. diff --git a/www/content/docs/reference/getstaticpathsfromcontext.mdx b/www/content/docs/reference/getstaticpathsfromcontext.mdx index 165fba37b..a0b7d4af7 100644 --- a/www/content/docs/reference/getstaticpathsfromcontext.mdx +++ b/www/content/docs/reference/getstaticpathsfromcontext.mdx @@ -24,7 +24,7 @@ const paths = await drupal.getStaticPathsFromContext( - `options` - Optional - `params: JsonApiParams`: JSON:API params such as `filter`, `fields`, `include` or `sort`. - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. - `pathPrefix: string`: Set the pathPrefix if you're calling from a subdir. Example: for `/articles/[...slug].tsx`, use `pathPrefix: "/articles"`. diff --git a/www/content/docs/reference/translatepath.mdx b/www/content/docs/reference/translatepath.mdx index 84aa0f53d..38d5b43ed 100644 --- a/www/content/docs/reference/translatepath.mdx +++ b/www/content/docs/reference/translatepath.mdx @@ -9,7 +9,7 @@ const path = await drupal.translatePath( options?: { withAuth, } -): Promise +): Promise ``` - `path: string` @@ -17,7 +17,7 @@ const path = await drupal.translatePath( - The resource path. Example: `/blog/slug-for-article`. - `options` - Optional - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. diff --git a/www/content/docs/reference/translatepathfromcontext.mdx b/www/content/docs/reference/translatepathfromcontext.mdx index d78233315..3d8d4c9e8 100644 --- a/www/content/docs/reference/translatepathfromcontext.mdx +++ b/www/content/docs/reference/translatepathfromcontext.mdx @@ -18,7 +18,7 @@ const path = await drupal.translatePathFromContext( - The context from `getStaticProps` or `getServerSideProps`. - `options` - Optional - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. - `pathPrefix: string`: Set the pathPrefix if you're calling from a subdir. Example: for `/articles/[...slug].tsx`, use `pathPrefix: "/articles"`. diff --git a/www/content/docs/reference/updateresource.mdx b/www/content/docs/reference/updateresource.mdx index db26de983..e46cf8be8 100644 --- a/www/content/docs/reference/updateresource.mdx +++ b/www/content/docs/reference/updateresource.mdx @@ -28,7 +28,7 @@ const resource = await drupal.updateResource( - `options` - Optional - `params: JsonApiParams`: JSON:API params such as `filter`, `fields`, `include` or `sort`. - - `withAuth: boolean | DrupalClientAuth`: + - `withAuth: boolean | NextDrupalAuth`: - Set the authentication method to use. See the [authentication docs](/docs/authentication). - Set to `true` to use the authentication method configured on the client. - `deserialize: boolean`: Set to false to return the raw JSON:API response. diff --git a/www/content/docs/serializer.mdx b/www/content/docs/serializer.mdx index 1afd0bea2..5596fa09d 100644 --- a/www/content/docs/serializer.mdx +++ b/www/content/docs/serializer.mdx @@ -3,7 +3,7 @@ title: Serializer excerpt: Using a custom serializer with DrupalClient. --- -The `DrupalClient` uses [jsona](https://github.com/olosegres/jsona) as the default serializer for serializing and deserializing JSON:API data. +The `NextDrupalPages` uses [jsona](https://github.com/olosegres/jsona) as the default serializer for serializing and deserializing JSON:API data. You can provide your own using the [`serializer`](/docs/client/configuration#serializer) option. @@ -14,7 +14,7 @@ You can provide your own using the [`serializer`](/docs/client/configuration#ser Here's how you can replace the default serializer with [jsonapi-serializer](https://github.com/SeyZ/jsonapi-serializer). ```ts title=lib/drupal.ts -import { DrupalClient } from "next-drupal" +import { NextDrupalPages } from "next-drupal" import { Deserializer } from "jsonapi-serializer" // Create a custom serializer. @@ -23,7 +23,7 @@ const customSerializer = new Deserializer({ }) // Pass the custom serializer to the client. -export const drupal = new DrupalClient( +export const drupal = new NextDrupalPages( process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { serializer: customSerializer, diff --git a/www/content/docs/typescript.mdx b/www/content/docs/typescript.mdx index de8b06134..12f29fe7c 100644 --- a/www/content/docs/typescript.mdx +++ b/www/content/docs/typescript.mdx @@ -1,9 +1,9 @@ --- title: TypeScript -excerpt: Using built-in types with DrupalClient. +excerpt: Using built-in types with NextDrupal client. --- -Every helper method for the `DrupalClient` has full TypeScript support. +Every helper method for the `NextDrupal` client has full TypeScript support. The `next-drupal` module ships with some default basic types you can use. @@ -132,10 +132,10 @@ export interface DrupalParagraph extends JsonApiResource { --- -### PathAlias +### DrupalPathAlias ```ts -export type PathAlias = { +export type DrupalPathAlias = { alias: string pid: number langcode: string @@ -144,18 +144,18 @@ export type PathAlias = { --- -### DrupalMenuLinkContent +### DrupalMenuItem ```ts -export interface DrupalMenuLinkContent { +export interface DrupalMenuItem { description: string enabled: boolean expanded: boolean - id: string + id: DrupalMenuItemId menu_name: string meta: Record options: Record - parent: string + parent: DrupalMenuItemId provider: string route: { name: string @@ -165,8 +165,10 @@ export interface DrupalMenuLinkContent { type: string url: string weight: string - items?: DrupalMenuLinkContent[] + items?: DrupalMenuItem[] } + +export type DrupalMenuItemId = string ``` --- @@ -204,6 +206,33 @@ export interface DrupalTranslatedPath { --- +### DrupalSearchApiJsonApiResponse + +```ts +export interface DrupalSearchApiJsonApiResponse extends JsonApiResponse { + meta: JsonApiResponse["meta"] & { + facets?: DrupalSearchApiFacet[] + } +} + +export interface DrupalSearchApiFacet { + id: string + label?: string + path?: string + terms?: { + url: string + values: { + value: string + label: string + active?: boolean + count?: number + } + }[] +} +``` + +--- + ## Extending Types To extend the built-in types, create a file at `types/drupal.d.ts` and extend the types as follows. diff --git a/www/content/docs/updating-resources.mdx b/www/content/docs/updating-resources.mdx index f1d6f4e9a..2032e2328 100644 --- a/www/content/docs/updating-resources.mdx +++ b/www/content/docs/updating-resources.mdx @@ -1,6 +1,6 @@ --- title: Updating Resources (PATCH) -excerpt: How to update JSON:API resources using DrupalClient. +excerpt: How to update JSON:API resources using NextDrupal client. --- @@ -9,13 +9,23 @@ The `updateResource` helper is available in `next-drupal ^1.4.0`. -The `DrupalClient` ships with a `updateResource` method for updating JSON:API resources. + + +If you're working with JSON:API, be mindful to select the option: + +`Accept all JSON:API create, read, update, and delete operations.` + +on the following path: `/admin/config/services/jsonapi` on Drupal. + + + +The `NextDrupal` client ships with a `updateResource` method for updating JSON:API resources. --- ## updateResource -### Update Resource +#### Update Resource ```ts const article = await drupal.updateResource( @@ -31,7 +41,7 @@ const article = await drupal.updateResource( ) ``` -### Update Resource with Relationships +#### Update Resource with Relationships ```ts const article = await drupal.updateResource( diff --git a/www/content/guides/jsonapi-params.mdx b/www/content/guides/jsonapi-params.mdx index 903fa9508..f3f7419b5 100644 --- a/www/content/guides/jsonapi-params.mdx +++ b/www/content/guides/jsonapi-params.mdx @@ -21,18 +21,17 @@ yarn add drupal-jsonapi-params import { DrupalNode } from "next-drupal" import { DrupalJsonApiParams } from "drupal-jsonapi-params" -export async function getStaticProps(context) { +export default async function ArticlePage() { // highlight-start const params = new DrupalJsonApiParams() - .addFields("node--blog_post", ["title", "path", "body", "uid"]) + .addFields("node--article", ["title", "path", "body", "uid"]) .addFilter("status", "1") .addInclude(["uid.user_picture"]) .addSort("created", "DESC") // highlight-end - const articles = await drupal.getResourceCollectionFromContext( + const article = await drupal.getResourceCollection( "node--article", - context, { params: params.getQueryObject(), // highlight-line } diff --git a/www/content/tutorials/preview-mode/configure-content-types.mdx b/www/content/tutorials/draft-mode/configure-content-types.mdx similarity index 57% rename from www/content/tutorials/preview-mode/configure-content-types.mdx rename to www/content/tutorials/draft-mode/configure-content-types.mdx index 0efbe0588..1bb3ab761 100644 --- a/www/content/tutorials/preview-mode/configure-content-types.mdx +++ b/www/content/tutorials/draft-mode/configure-content-types.mdx @@ -2,20 +2,20 @@ title: Configure Content Types excerpt: Configure preview for content types weight: 150 -group: Preview Mode +group: Draft Mode --- -Next, we need to configure preview mode for the content types. This will display an inline preview in an iframe when you visit the content pages. +Next, we need to configure draft mode for the content types. This will display an inline draft in an iframe when you visit the content pages. --- -## Configure Preview +## Configure Draft -To enable content preview inside Drupal, we need to configure a site resolver for the **Article** content type. +To enable content draft inside Drupal, we need to configure a site resolver for the **Article** content type. -A _site resolver_ tells Drupal how to resolve the preview URL for an entity. +A _site resolver_ tells Drupal how to resolve the draft URL for an entity. diff --git a/www/content/tutorials/draft-mode/configure-draft-routes.mdx b/www/content/tutorials/draft-mode/configure-draft-routes.mdx new file mode 100644 index 000000000..b10eee73e --- /dev/null +++ b/www/content/tutorials/draft-mode/configure-draft-routes.mdx @@ -0,0 +1,39 @@ +--- +title: Configure Draft Routes +excerpt: Draft routes in Next.js +weight: 140 +group: Draft Mode +--- + +Implement draft mode using two API routes. + + + +If you're using the Basic Starter, draft routes are already created for you. + + + +## /app/api/draft/route.ts + +```ts title=app/api/draft/route.ts +import { drupal } from "@/lib/drupal" +import { enableDraftMode } from "next-drupal/draft" +import type { NextRequest } from "next/server" + +export async function GET(request: NextRequest): Promise { + return enableDraftMode(request, drupal) +} +``` + +--- + +## /app/api/disable-draft/route.ts + +```ts title=app/api/disable-draft/route.ts +import { disableDraftMode } from "next-drupal/draft" +import type { NextRequest } from "next/server" + +export async function GET(request: NextRequest) { + return disableDraftMode() +} +``` diff --git a/www/content/tutorials/preview-mode/create-oauth-client.mdx b/www/content/tutorials/draft-mode/create-oauth-client.mdx similarity index 86% rename from www/content/tutorials/preview-mode/create-oauth-client.mdx rename to www/content/tutorials/draft-mode/create-oauth-client.mdx index 7bb38b660..3983f9698 100644 --- a/www/content/tutorials/preview-mode/create-oauth-client.mdx +++ b/www/content/tutorials/draft-mode/create-oauth-client.mdx @@ -2,7 +2,7 @@ title: Create OAuth Client excerpt: Setup an OAuth client to be used for authenticated content. weight: 110 -group: Preview Mode +group: Draft Mode --- Before we can create an OAuth consumer, we need to create a new role and a user for OAuth scopes. @@ -38,7 +38,7 @@ We are assigning the _Bypass content access control_ permission to allow Next.js This scope is only going to be used when making authenticated requests from Next.js to Drupal. ```ts -const articles = await drupal.getResource( +const article = await drupal.getResource( "node--article", "dad82fe9-f2b7-463e-8c5f-02f73018d6cb", // highlight-start @@ -108,20 +108,17 @@ DRUPAL_CLIENT_SECRET= --- -## 7. Update DrupalClient +## 7. Update NextDrupal client. -Update the `DrupalClient` to use the **Bearer** authentication header. +Update the `NextDrupal` to use the **Bearer** authentication header. ```ts title=lib/drupal.ts -import { DrupalClient } from "next-drupal" - -export const drupal = new DrupalClient( - process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, - { - auth: { - clientId: process.env.DRUPAL_CLIENT_ID, - clientSecret: process.env.DRUPAL_CLIENT_SECRET, - }, - } -) +import { NextDrupal } from "next-drupal" + +export const drupal = new NextDrupal(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, { + auth: { + clientId: process.env.DRUPAL_CLIENT_ID, + clientSecret: process.env.DRUPAL_CLIENT_SECRET, + }, +}) ``` diff --git a/www/content/tutorials/preview-mode/create-site.mdx b/www/content/tutorials/draft-mode/create-site.mdx similarity index 68% rename from www/content/tutorials/preview-mode/create-site.mdx rename to www/content/tutorials/draft-mode/create-site.mdx index fcc43a8f8..8dc4cfe72 100644 --- a/www/content/tutorials/preview-mode/create-site.mdx +++ b/www/content/tutorials/draft-mode/create-site.mdx @@ -2,10 +2,10 @@ title: Create Next.js site excerpt: Create a Next.js site on Drupal weight: 105 -group: Preview Mode +group: Draft Mode --- -Start by creating a Next.js site so that we can render the preview on Drupal. +Start by creating a Next.js site so that we can render the draft in Drupal. 1. Visit `/admin/config/services/next`. 2. Click **Add Next.js site**. @@ -13,8 +13,8 @@ Start by creating a Next.js site so that we can render the preview on Drupal. - **Label**: `Next.js` - **Base URL**: `http://localhost:3000` -- **Preview URL**: `http://localhost:3000/api/preview` -- **Preview secret**: `secret` +- **Draft URL (or Preview URL)**: `http://localhost:3000/api/draft` +- **Secret key**: `secret` diff --git a/www/content/tutorials/preview-mode/done.mdx b/www/content/tutorials/draft-mode/done.mdx similarity index 66% rename from www/content/tutorials/preview-mode/done.mdx rename to www/content/tutorials/draft-mode/done.mdx index 19ff28660..a350ab534 100644 --- a/www/content/tutorials/preview-mode/done.mdx +++ b/www/content/tutorials/draft-mode/done.mdx @@ -1,10 +1,10 @@ --- title: Done weight: 160 -group: Preview Mode +group: Draft Mode --- -Congratulations. You have successfully configured preview mode for your content types. +Congratulations. You have successfully configured draft mode for your content types. You should see the iframe preview when you visit your content pages. diff --git a/www/content/tutorials/draft-mode/index.mdx b/www/content/tutorials/draft-mode/index.mdx new file mode 100644 index 000000000..23ebdb68b --- /dev/null +++ b/www/content/tutorials/draft-mode/index.mdx @@ -0,0 +1,10 @@ +--- +title: Draft Mode +excerpt: Enable draft mode for content types. +weight: 100 +group: Draft Mode +--- + +The Next.js module, paired with the `next-drupal` plugin, makes it easy to create [Next.js draft routes](https://nextjs.org/docs/app/building-your-application/configuring/draft-mode). + +To handle draft routes, we need to create a Next.js site on Drupal and configure authentication. diff --git a/www/content/tutorials/graphql/index.mdx b/www/content/tutorials/graphql/index.mdx index 6d1264202..a1659dc65 100644 --- a/www/content/tutorials/graphql/index.mdx +++ b/www/content/tutorials/graphql/index.mdx @@ -5,7 +5,7 @@ weight: 10 group: Quick Start (GraphQL) --- -This tutorial will help you get started with Next.js for Drupal using the [`DrupalClient`](/docs/client) and **GraphQL**. +This tutorial will help you get started with Next.js for Drupal using the [`NextDrupal`](/docs/client) and **GraphQL**. diff --git a/www/content/tutorials/on-demand-revalidation/configure-revalidate-route.mdx b/www/content/tutorials/on-demand-revalidation/configure-revalidate-route.mdx index 63bf6f073..303611bb8 100644 --- a/www/content/tutorials/on-demand-revalidation/configure-revalidate-route.mdx +++ b/www/content/tutorials/on-demand-revalidation/configure-revalidate-route.mdx @@ -5,7 +5,7 @@ weight: 360 group: On-demand Revalidation --- -Implement on-demand revalidation using an API routes at `/revalidate`. +Implement on-demand revalidation using an API route at `/revalidate`. @@ -13,36 +13,35 @@ If you're using the Basic Starter, revalidate route are already created for you. -## /pages/api/revalidate.ts +## /app/api/revalidate/route.ts -```ts title=pages/api/revalidate.ts -import { NextApiRequest, NextApiResponse } from "next" +```ts title=app/api/revalidate/route.ts +import { revalidatePath } from "next/cache" +import type { NextRequest } from "next/server" -export default async function handler( - request: NextApiRequest, - response: NextApiResponse -) { - let slug = request.query.slug as string - const secret = request.query.secret as string +async function handler(request: NextRequest) { + const searchParams = request.nextUrl.searchParams + const path = searchParams.get("path") + const secret = searchParams.get("secret") // Validate secret. if (secret !== process.env.DRUPAL_REVALIDATE_SECRET) { - return response.status(401).json({ message: "Invalid secret." }) + return new Response("Invalid secret.", { status: 401 }) } - // Validate slug. - if (!slug) { - return response.status(400).json({ message: "Invalid slug." }) + // Validate path. + if (!path) { + return new Response("Invalid path.", { status: 400 }) } try { - await response.revalidate(slug) + revalidatePath(path) - return response.json({}) + return new Response("Revalidated.") } catch (error) { - return response.status(404).json({ - message: error.message, - }) + return new Response((error as Error).message, { status: 500 }) } } + +export { handler as GET, handler as POST } ``` diff --git a/www/content/tutorials/on-demand-revalidation/index.mdx b/www/content/tutorials/on-demand-revalidation/index.mdx index c8a7f329b..b6966acf1 100644 --- a/www/content/tutorials/on-demand-revalidation/index.mdx +++ b/www/content/tutorials/on-demand-revalidation/index.mdx @@ -5,6 +5,6 @@ weight: 300 group: On-demand Revalidation --- -[On-demand Revalidation](https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration#on-demand-revalidation) makes it easy to update your Next.js site when content on Drupal is created, updated or deleted. +[On-demand Revalidation](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#on-demand-revalidation) makes it easy to update your Next.js site when content on Drupal is created, updated or deleted. Starting with `v1.6.0`, Next.js for Drupal supports On-demand Revalidation configurable per entity types. diff --git a/www/content/tutorials/preview-mode/configure-preview-routes.mdx b/www/content/tutorials/preview-mode/configure-preview-routes.mdx deleted file mode 100644 index e49d7b3fd..000000000 --- a/www/content/tutorials/preview-mode/configure-preview-routes.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Configure Preview Routes -excerpt: Preview routes in Next.js -weight: 140 -group: Preview Mode ---- - -Implement preview mode using two API routes. - - - -If you're using the Basic Starter, preview routes are already created for you. - - - -## /pages/api/preview.ts - -```ts title=pages/api/preview.ts -import { NextApiRequest, NextApiResponse } from "next" - -import { drupal } from "lib/drupal" - -export default async function handler( - request: NextApiRequest, - response: NextApiResponse -) { - return await drupal.preview(request, response) -} -``` - ---- - -## /pages/api/exit-preview.ts - -```ts title=pages/api/exit-preview.ts -import { NextApiResponse } from "next" - -export default function exit(_, response: NextApiResponse) { - response.clearPreviewData() - response.writeHead(307, { Location: "/" }) - response.end() -} -``` diff --git a/www/content/tutorials/preview-mode/index.mdx b/www/content/tutorials/preview-mode/index.mdx deleted file mode 100644 index efa24661e..000000000 --- a/www/content/tutorials/preview-mode/index.mdx +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Preview Mode -excerpt: Enable preview mode for content types. -weight: 100 -group: Preview Mode ---- - -The Next.js module, paired with the `next-drupal` plugin, makes it easy to create [Next.js preview routes](https://nextjs.org/docs/advanced-features/preview-mode). - -To handle preview routes, we need to create a Next.js site on Drupal and configure authentication. diff --git a/www/content/tutorials/quick-start/configure-path-aliases.mdx b/www/content/tutorials/quick-start/configure-path-aliases.mdx index e73b89d9a..86f9b4dfe 100644 --- a/www/content/tutorials/quick-start/configure-path-aliases.mdx +++ b/www/content/tutorials/quick-start/configure-path-aliases.mdx @@ -5,7 +5,7 @@ weight: 50 group: Quick Start --- -The `next-drupal` plugin uses paths to resolve resources for `getStaticProps`. To make this work, we need to configure path aliases for our content types. +The `next-drupal` plugin uses paths to resolve resources for the Next.js Frontend. To make this work, we need to configure path aliases for our content types. Let's add a pattern for the **Article** content type. diff --git a/www/content/tutorials/quick-start/index.mdx b/www/content/tutorials/quick-start/index.mdx index e777be58a..205ce5de0 100644 --- a/www/content/tutorials/quick-start/index.mdx +++ b/www/content/tutorials/quick-start/index.mdx @@ -5,7 +5,7 @@ weight: 10 group: Quick Start --- -This tutorial will help you get started with Next.js for Drupal using the [`DrupalClient`](/docs/client) and **JSON:API**. +This tutorial will help you get started with Next.js for Drupal using the [`NextDrupal Client`](/docs/client) and **JSON:API**. diff --git a/www/next.config.js b/www/next.config.js index c68883db7..47b3c7b7f 100644 --- a/www/next.config.js +++ b/www/next.config.js @@ -48,8 +48,8 @@ module.exports = { permanent: true, }, { - source: "/docs/client/serializer", - destination: "/docs/serializer", + source: "/docs/client/deserializer", + destination: "/docs/deserializer", permanent: true, }, { @@ -74,7 +74,7 @@ module.exports = { }, { source: "/docs/client/preview-mode", - destination: "/docs/preview-mode", + destination: "/docs/draft-mode", permanent: true, }, {