Skip to content

Use Druxt in a Node application

Use Druxt's framework-agnostic clients from plain Node, via the druxt-inspect CLI in the node-client example.

Before you start: this guide assumes a Drupal backend with Druxt enabled (see Getting started) and Node with access to the druxt package.

Everything below Nuxt - DruxtClient, DruxtRouter, DruxtSchema, the Vuex store modules - is plain, dependency-light JavaScript with no Vue or Nuxt requirement. The examples/node-client package in the druxt.js monorepo proves it: a standalone Node CLI, druxt-inspect, built directly on druxt and druxt-schema with no framework in between.

It's a practical backend-inspection tool (and a convenient way for AI agents to discover a Druxt site's shape via --json), and a reference for using the clients programmatically in any Node environment.

Installation and setup

The CLI runs straight from the checked-out monorepo - its only dependencies are the workspace druxt and druxt-schema packages (run yarn build in the repo root once if packages/*/dist doesn't exist yet):

cd examples/node-client
node bin/druxt-inspect.js --help

Point it at any Druxt-enabled Drupal backend, either with --baseUrl or the DRUXT_BASE_URL environment variable. The examples in this site assume the docs/drupal Umami backend on http://127.0.0.1:8888.

Commands

types - list resource types

druxt-inspect -b http://127.0.0.1:8888 types
RESOURCE TYPE                                         ENDPOINT
----------------------------------------------------  --------
action--action                                        .../jsonapi/action/action
block--block                                          .../jsonapi/block/block
block_content--banner_block                           .../jsonapi/block_content/banner_block
node--recipe                                          .../jsonapi/node/recipe
...

schema <resourceType> - display mode schemas

Prints the Druxt view and form schemas for a resource type and display mode. These are the same schemas druxt-entity uses to render entities - field order, labels, formatters, and settings.

druxt-inspect -b http://127.0.0.1:8888 schema node--recipe --mode card
{
  "id": "node--recipe--card--view",
  "resourceType": "node--recipe",
  "fields": [
    { "id": "field_difficulty", "label": { "text": "Difficulty", "position": "hidden" }, "type": "list_default", ... },
    { "id": "field_media_image", "label": { "text": "Media Image", "position": "hidden" }, "type": "entity_reference_entity_view", ... }
  ]
}

stubs <resourceType> - generate wrapper stubs

Writes the boilerplate for a Druxt Entity wrapper component - one slot per schema field, named and registered the way DruxtEntity's wrapper resolution expects. A themed component can start from this and move fields into markup:

druxt-inspect -b http://127.0.0.1:8888 stubs node--recipe --mode card --output components/druxt/entity/node
<template>
  <div>
    <!-- Difficulty (list_default) -->
    <slot name="field_difficulty" />
    <!-- Media Image (entity_reference_entity_view) -->
    <slot name="field_media_image" />
  </div>
</template>

<script>
// Druxt Entity wrapper generated by druxt-inspect for schema 'node--recipe--card--view'.
// See https://druxtjs.org for theming documentation.
import { DruxtEntityMixin } from 'druxt-entity';

export default {
  name: 'DruxtEntityNodeRecipeCard',

  mixins: [DruxtEntityMixin],
};
</script>

sample <resourceType> - fetch entities

druxt-inspect -b http://127.0.0.1:8888 sample node--recipe --limit 3
UUID                                  LANG   LABEL
------------------------------------  ----   -----
62a560b5-1954-4bf7-ba87-609ce73675e0  en     Deep mediterranean quiche
67f44980-de26-4567-82f4-b058595720ec  en     Vegan chocolate and nut brownies
...

views - list Views and displays

Lists the Views exposed by the JSON:API Views module. The displays line is what a DruxtView component (<DruxtView viewId="recipes" displayId="page_1" />) or the views--<viewId> resource convention can query.

druxt-inspect -b http://127.0.0.1:8888 views
VIEW                LABEL
------------------  -----
archive             Archive
                    displays: block_1, default, page_1
recipes             Recipes
                    displays: block_1, default, page_1
...

--json everywhere

Every command takes --json for machine-readable output - useful for scripting, and for letting an AI agent discover a site's types, schemas, and content before writing components against them.

Using the clients programmatically

The CLI is a thin layer over the same classes Nuxt injects for you. In any Node process:

const { DruxtClient } = require('druxt');

const druxt = new DruxtClient('http://127.0.0.1:8888');

// The JSON:API index.
const index = await druxt.getIndex();

// A collection, one page.
const collection = await druxt.getCollection('node--recipe');

// A single resource by UUID, with JSON:API query filtering.
const recipe = await druxt.getResource('node--recipe', uuid, {
  'fields[node--recipe]': 'title,field_ingredients',
});

// Every page of a collection.
const collections = await druxt.getCollectionAll('node--recipe');

DruxtClient also accepts an axios instance via options.axios - the same injection point Nuxt's plugin uses - which is how the CLI's test suite runs against recorded JSON:API fixtures with zero network access. See examples/node-client/test/adapter.js for the pattern, and the DruxtClient API reference for the full method list.

Testing without a backend

examples/node-client includes a Jest suite that replays recorded JSON:API responses through that axios injection - no Drupal required:

# from the druxt.js repo root
yarn test:node-client

# or from the example itself
cd examples/node-client && yarn test

Fixtures are re-recorded against a live backend only when the data actually needs to change: cd examples/node-client && DRUXT_BASE_URL=... node test/record.js.