Best practices, basic steps, lists of tools and tips to help you integrate a Drupal 8.x+ backend with a JavaScript frontend.
Note: Some examples below refer only to React development and are not JS agnostic.
Table of Contents
Online services to use when comparing frameworks (trends, popularity, usage, downloads, benchmarks etc).
- Questionnaires
- Trends
- Popularity
- https://www.githubcompare.com/vercel/next.js+facebook/react+angular/angular.js+vuejs/vue
- https://star-history.com/#facebook/react&vuejs/vue&angular/angular&vercel/next.js&Timeline
- https://www.hntrends.com/2020/dec-year-unlike-any-other-tech-tools-didnt-change-much.html?compare=AngularJS&compare=Ember&compare=React&compare=Vue
- https://frontpagemetrics.com/r/reactjs#compare=vuejs+angular2+sveltejs+nextjs
- Usage
- Analysis & dependencies
- Benchmarks
- Browser Support
- Performance
- Stability
- Development experience
- Documentation and support
- Vendors behind
- Complexity and learning curve
- CRUD requirements
- Serving multiple platforms and consumers
- Existing in-house knowledge
Note: Before using these tools try to use the built-in, bundled tools you get from each framework.
- VSCode
- nvm, npm (no need to use
yarn
overnpm
in 2022) - Typescript
- Storybook
- Babel
- PostCSS
- husky
- JSX
- JSON, JSON API
- Bundlers: Webpack, esbuild
- Code linting etc: EditorConfig, ESLint, Prettier, JSLint
- Code generators: Hygen, nx, ReexJs CLI, generact
- Testing: Jest, Cypress, testing-library, nightwatchjs, playwright
- Data fetch: axios, react-query, SWR, node-fetch
- Data parser: qs, html-react-parser
- Routing: React Router
- Quality: danger
- Logging: pino
- Documentation: jsdoc
- Performance: next-boost, react-lazy-load-image-component, node-cache, webpack-bundle-analyzer
- Security: (npm built-in:
npm-audit, npm-outdated, npm-doctor
npm-check, snyk, npm-check-updates - State management: redux, zustand, recoil, jotai
- Translations, i18n: lingui, polyglot
- Mocks, faker: sinon, faker, JSON Server fake API
In order to start with JS you sould be familiar with the basic terms below. Note that some of them may refer to a specific JS framework.
- CORS
- Cache
- Code splitting
- Components
- Composition
- DOM
- Data fetch
- HMR (Hot Module Reload)
- HOC (Higher Order Components)
- Hook events
- Injection
- Invalidation
- Isomorphic
- PWA
- Props
- Routing
- SEO
- SSR, SSG, ISR, DSG, CSR
- SWA
- SideEffect
- State
- Web Vitals (LCP, FID, CLS)
- a11y
- es6/es7 etc
- hydration
- i18n
- library
- module
- node daemon
- package
- virtual DOM
- Move files around until it feels right
- Group by file type
- Avoid too much nesting
- Keep with the trends (e.g. use common names like "
src, public, pages, __tests__, docs
" etc
ToDo: Add some example structure here..
- Prefer "CSS in files" approach except if there are specific requirements.
- For inline styles you can use utility CSS libraries like tailwindcss and Windi CSS.
- For UI building isolation and sandboxing use Storybook, React Styleguidist, React Cosmos, React Preview etc.
- https://www.drupal.org/docs/develop/decoupled-drupal
- Drupal core ideas: Drupal JavaScript Client Initiative
- https://dri.es/headless-cms-rest-vs-jsonapi-vs-graphql
- https://dri.es/how-to-decouple-drupal-in-2019
- https://dri.es/drupal-looking-to-adopt-react
- https://dri.es/advancing-drupal-web-services
- https://www.drupal.org/industries/decoupled
- https://www.lullabot.com/articles/should-you-decouple
- https://www.softescu.com/en/blog/fully-decoupled-or-progressively-decoupled
- https://medium.com/analytics-vidhya/decoupled-drupal-as-a-solution-bd0ec25f39cf
- https://opensenselabs.com/blog/articles/different-options-decoupling-drupal
- https://www.lullabot.com/articles/decoupled-hard-problems-routing
- https://noti.st/brianperry/2Fvgeu/drupal-state-and-the-need-for-a-javascript-sdk
- My Headless/Decoupled CMS Comparison Matrix, 2017, krynsky.com
- #decoupled
- #headless
- #graphql
- #contenta
- #react
- #nextjs
- #gatsby
- #druxt (NuxtJS)
- #vue
- #custom-elements
Note: Modules in emphasis are the most used across the Drupal universe.
jsonapi.org, JSON API: Drupal core module documentation, Ecosystem modules for JSON:API
- Basic
- decoupled_kit
- decoupled_menus
- drupal_jsonapi_params
- entity_view_mode_normalize
- fieldable_path
- jsonapi_aliases
- jsonapi_comment
- jsonapi_embed
- jsonapi_extras
- jsonapi_menu_items
- jsonapi_views
- jsonrpc
- pager_serializer
- rest_absolute_urls
- rest_menu_detail
- rest_menu_items
- rest_normalizer
- jsonapi_hypermedia
- jsonapi_bulk_exclude
- jsonapi_example
- https://github.com/pmelab/contextual_aliases
- Data
- Subrequests, nesting
- Routing
- Collections
- Search
- Preview
- Performance
- Images/Files
- Rate limits
- API Documentation
- Authentication
- Administration
- Forms
- Logging
- Translations
(Advice: Do not prefer GraphQL over JSON API except if there are special requirements)
- graphql
- graphql_compose
- graphql_entity_by_object
- graphql_entity_definitions
- graphql_extras
- graphql_formatters
- graphql_menu
- graphql_metatag
- graphql_node_preview
- graphql_redirect
- graphql_redirect_entity
- graphql_search_api
- graphql_views
- graphql_webform
- preview_graphql
- https://www.contentacms.org
- https://www.drupal.org/project/tide
- https://github.com/systemseed/falcon
- https://github.com/codingsasi/acephalous
- https://www.drupal.org/project/ezcontent (using REST, not a decoupled example)
- https://next-drupal.org (Next)
- https://druxtjs.org (Nuxt)
- https://stack.lupus.digital (Nuxt)
- https://github.com/acquia/next-acms (Next)
- d8-jsonapi-querystring
- d8-subrequests
- drupal-jsonapi-extractor
- drupal-jsonapi-params
- drupal-sdk
- drupal-state (see docs at drupalcode.org/drupal_state
- jsonapi-parse
- react-drupal-json-api
- drupal-kit
- drupal-js-sdk
- Displaying embedded entities on CKEditor (eg Media) inside JS components
- Multilingual
- Subrequets and relationships in data
- Customizing of responses like filtering, quering and altering
- Routing and path aliases
- Non entities data (e.g. metatags, redirects, path aliases, image styles)
- Workflows (Content Moderation) and revisions
- Node preview
- Authentication
- Invalidate partial cache
- Forms
An example matrix for common requirements of a decoupled Drupal backend with JS frontend.
The table show which part of the app should take care of each functionality.
For example, we could get the site logo from Drupal but we could also use a static image on the JS side as a logo.
Notice that, in some cases, there may be a combination of the two parts or a 3rd party solution (eg an external CDN for image assets).
Requirement | Drupal backend | JS frontend |
---|---|---|
access and permissions | ⬜ | ⬜ |
authentication | ⬜ | ⬜ |
basic site settings (eg logo, site name, site slogan etc) | ⬜ | ⬜ |
breadcrumbs | ⬜ | ⬜ |
caching | ⬜ | ⬜ |
collections (views VS JSON API entity queries) | ⬜ | ⬜ |
CORS | ⬜ | ⬜ |
CRUD requirements | ⬜ | ⬜ |
embedded HTML on CKEditor | ⬜ | ⬜ |
file attachments | ⬜ | ⬜ |
forms | ⬜ | ⬜ |
image styles | ⬜ | ⬜ |
menus | ⬜ | ⬜ |
metatags | ⬜ | ⬜ |
mocking data | ⬜ | ⬜ |
modifying JSON response | ⬜ | ⬜ |
multilingual | ⬜ | ⬜ |
multisite | ⬜ | ⬜ |
partial cache invalidation | ⬜ | ⬜ |
path aliases | ⬜ | ⬜ |
preview | ⬜ | ⬜ |
redirects | ⬜ | ⬜ |
relationships and field references | ⬜ | ⬜ |
revisions | ⬜ | ⬜ |
routing | ⬜ | ⬜ |
search_api | ⬜ | ⬜ |
sub-requests | ⬜ | ⬜ |
third party scripts (eg gtag) | ⬜ | ⬜ |
UI translations | ⬜ | ⬜ |
workflows (content moderation) | ⬜ | ⬜ |
xml sitemap | ⬜ | ⬜ |
- https://reactjs.org
- https://github.com/enaqx/awesome-react
- https://github.com/brillout/awesome-react-components
- Thinking in React - reactjs.org
- Complete guide React + Drupal - drupalize.me
- React in patterns
- 30 Days of React - GitHub
- Functional Components
- React Components: https://reactjs.org/docs/react-component.html, https://github.com/brillout/awesome-react-components
- React Hooks: https://reactjs.org/docs/hooks-intro.html, https://usehooks.com
- React Props: https://akd3257.medium.com/what-are-props-in-react-2f822330e3a7
- Guide: https://reactfordrupal.com
- Starter: https://github.com/systemseed/drupal_reactjs_boilerplate
- Example: https://github.com/DrupalizeMe/react-and-drupal-examples
- Better SEO. Supports SSR, SSG, ISR.
- Built in solutions for common requirements (routing, head/metatags, images, links, font optimization, data fetching, injected scripts, i18n, AMP)
- Built in tools (Typescript, Sass, ESLint, Webpack, env variables, preview mode, polyfills)
- Better Development Experience (DX) (zero config, built in tools, fast refresh)
- Based on React (can use all the React goodies)
- next-drupal.org
- TallerWebSolutions/next-on-drupal
- About Drupal, Gatsby and Next
- Next.js and Headless CMS - GitHub issue
- https://swr.vercel.app (React Hooks for Data Fetching)
- https://next-auth.js.org (Authentication for Next.js)
- https://github.com/atilafassina/next-g11n (Translate and localize your Next.js app smoothly)
- https://github.com/next-boost/next-boost (Adds a cache layer to your SSR applications)
- https://www.smashingmagazine.com/2021/11/maintain-large-nextjs-application
- https://stackabuse.com/guide-to-getting-started-with-nextjs-create-a-nextjs-app
- Better SEO. Suppports SSR and SSG.
- Built in solutions for common requirements (routing, head/metatags, images, links, font optimization, data fetching, injected scripts, i18n, AMP)
- Built in tools (Typescript, Sass, ESLint, Webpack, env variables, preview mode, polyfills)
- Better Development Experience (DX) (zero config, built in tools, fast refresh)
- Based on Vue (can use all the Vue goodies)
Druxt = DRUpal + nuXT
- druxtjs.org
- Fully Decoupled Drupal, with Nuxt.js in the frontend.
- Drupal JSON:API Client with Vuex caching.
- Modular Vue.js component library system.
- Slot and Wrapper theming system.
- API and File proxy.
- Make it really "decoupled" (except if other requirements)
- Keep it simple. Use the basic tools and extend when needed.
- Less JS packages and less Drupal modules is prefferable.
- Work only with NodeJS LTS versions.
- Think in Components
- Create enough Components
- Modify the state directly
- Add keys on the lists (inside JS Components)
- Declare types, validate functions
- Always test your Components and app
- Dockerize your JS app
- For security updates of npm packages prefer to update the main JS library used (eg Next, React etc) and not the several npm packages independently.
- Drupal: Prefer Drupal modules from core (e.g. JSON API instead of GraphQL)
- Drupal: Do not override the default Drupal field machine names on JSON
- Drupal: prefer quering the
search_api
to get search results on the JS App when using 3rd party search engines like SOLR. - Start with the official starter kits (e.g create-react-app)
MIT - Copyright (c) 2022 EWORX S.A.