next-drupal

repository·main·Indexed 20 days ago

https://github.com/chapter-three/next-drupal

A Composer template and library for managing Drupal projects and connecting them to Next.js frontends. It provides a standardized directory structure, automated scaffolding, and the DrupalClient for interacting with Drupal's JSON:API or GraphQL endpoints. Features include support for custom caching via the DataCache interface, custom fetch adapters, custom serializers, and various authentication implementations including OAuth2 and Basic Auth.

Tokens
58.7K
Snippets
197
Records
266
Agent score
72%

What's inside next-drupal

  1. Overview of NextDrupal client features

    main

    The NextDrupal client is a JSON:API client designed to bridge Drupal data with Next.js. It supports both read operations (fetching data for static generation or server-side rendering) and write operations (POST, PATCH, and DELETE) to create or modify Drupal resources directly from Next.js.

    Key capabilities include:

    • Resource Helpers: Specialized methods for fetching resources, menus, views, and search indices.
    • Customizable Authentication: Supports Bearer, Basic, Next-Auth, or custom implementations.
    • Extensibility: Support for custom serializers and custom fetchers.
    • Caching: Support for various caching layers such as memory cache or Redis.
    • Error Handling: Provides human-readable error messages.
  2. Manage Drush commands and configuration

    main
    The drupal/drush directory provides the necessary commands, configuration, and site aliases required to use Drush within this project. Drush is a command-line shell for Drupal that allows you to manage your site via the terminal. For a full list of available Drush commands, refer to the official Drush documentation on Packagist.
  3. What is a revalidator plugin?

    main

    A revalidator plugin is a configuration component that tells Drupal how to trigger revalidation in Next.js when an entity is created, updated, or deleted.

    There are two primary types of revalidation strategies available:

    • Cache Tag: Uses Drupal's cache tags to invalidate content.
    • Path: Uses specific URL paths to trigger revalidation, which can include the entity's own path and Additional paths for related landing pages.
  4. Determine if you need CORS configuration

    main

    In next-drupal version 2.x and later, CORS is disabled by default for security.

    You do NOT need CORS if you use:

    • getStaticProps or getServerSideProps
    • React Server Components
    • Next.js API routes
    • Next.js Server Actions

    You DO need CORS if you:

    • Perform client-side fetch() calls directly from the browser to your Drupal instance.

    Best Practice: Instead of enabling CORS, use Next.js API routes or Server Actions as a proxy. This allows your client to fetch from the same-origin Next.js server, which then fetches from Drupal server-side. This is more secure and avoids CORS issues entirely.

  5. Handle multiple entity types in a single dynamic route

    main

    You can handle multiple resource types (e.g., node--page and node--article) in one [...slug]/page.tsx file by using drupal.translatePath(slug).

    translatePath returns an object containing information about the resource type, including jsonapi.resourceName and the entity details. This allows you to conditionally fetch specific fields using DrupalJsonApiParams based on the detected type.

    import { DrupalJsonApiParams } from "drupal-jsonapi-params"
    
    export async function generateStaticParams() {
      const resources = await drupal.getResourceCollectionPathSegments(
        ["node--page", "node--article"]
      );
      return resources.map((resource) => ({ slug: resource.segments }));
    }
    
    export default function Page({ params }) {
      const { slug } = params;
      const path = drupal.translatePath(slug)
      const type = path.jsonapi.resourceName
    
      const params = new DrupalJsonApiParams()
    
      if (type === "node--page") {
        params.addFields("node--page", ["title", "path", "body"])
      }
    
      if (type === "node--article") {
        params.addFields("node--article", ["title", "path", "body", "uid"])
      }
    
      const node = await drupal.getResource(path, path.entity.uuid, {
        params: params.getQueryObject(),
      })
    
      if (node.type === "node--page") return <PageComponent node={node}/>
      if (node.type === "node--article") return <ArticleComponent node={node}/>
      return null
    }
  6. Choose an authentication grant for Next.js and Drupal

    main

    To authenticate Drupal users in a Next.js application, you must implement an OAuth2 grant to acquire access tokens. There are two primary methods available:

    1. Password Grant: Users authenticate directly with a username and password.
      • Constraint: Use this for first-party clients only (i.e., you own both the Next.js site and the Drupal site).
    2. Authorization Code Grant: The user is redirected off-site to the Drupal site (the authorization server) to perform the authentication.

    Your choice depends on the client type and the desired user experience.

  7. How Revalidator plugins work

    main

    To support On-demand Revalidation in Next.js, next-drupal uses Revalidator plugins.

    A Revalidator plugin triggers revalidation for one or more Next.js sites whenever a Drupal entity undergoes an insert, update, or delete action.

    By default, the next module includes the Path revalidator, which revalidates sites based on the entity's path. You can implement custom logic by creating your own plugins using the Drupal Plugin API.

  8. Configure authentication in NextDrupal

    main

    Authentication in NextDrupal can be configured at two levels:

    1. Client Authentication: Set globally when instantiating the NextDrupal client. This is the recommended approach for fetching and building static pages.
    2. Method Authentication: Set per individual method call using the withAuth option. This is typically used for session-based or user-based authentication calls where the credentials change per request.

    Supported authentication types include Bearer tokens, Basic auth, custom Callbacks, and direct Access Tokens.

    import { NextDrupal } from "next-drupal"
    
    // Global Client Authentication
    export const drupal = new NextDrupal(
      process.env.NEXT_PUBLIC_DRUPAL_BASE_URL,
      {
        auth: // Configure global auth here
      }
    )
    
    // Per-method Authentication
    const userArticles = await drupal.getResourceCollection("node--article", {
      params: {
        "filter[uid]": user.id,
      },
      withAuth: // Set custom auth here
    })
  9. CORS configuration considerations for Next.js

    main

    When configuring CORS for a Next.js integration, keep the following in mind:

    • Subdomains: Different subdomains are treated as different origins. For example, www.site.com and cms.site.com are not the same; you must list each explicitly in allowedOrigins.
    • Preview Mode: Next.js Preview mode uses server-side authentication and does not require CORS.
    • On-demand Revalidation: This process involves Drupal calling Next.js; it does not require CORS configuration on the Drupal side.
    • Environment-specific config: For local development, it is recommended to use development.services.yml (which is typically loaded via settings.local.php) to manage local origins like http://localhost:3000 separately from production settings.
  10. Use Next.js for Drupal without authentication

    main
    Authentication is not strictly required for all use cases. You can use Next.js for Drupal to pull public JSON:API data and build static pages without any authentication setup. Authentication is only necessary when you need to preview unpublished entities or specific revisions.