/next-drupal

Drupal implementation for nextjs using next-drupal package

Primary LanguageTypeScript

Next-drupal

Getting started

There is no release for any of the packages under this repo. To use it please make use of mrs-developer.

  1. Install Nextjs project using pages directory. Note: only next@13.x.x is supported because of next-auth dependency.

  2. Add the following scripts under your package.json:

{
   "scripts": {
      "develop": "npx --yes -p mrs-developer missdev --output=../workspaces --no-config",
      "develop:npx": "npx --yes -p mrs-developer missdev --output=../workspaces --no-config"
   }
}
  1. Add pnpm-workspace.yaml file in your project root, containing:
packages:
  - 'workspaces/**/packages/*'
  1. Add desired dependencies:
{
   "dependencies": {
      "@edw/base": "workspace:*",
      "@edw/drupal": "workspace:*",
   },
   "devDependencies": {
      "eslint-config-custom": "workspace:*",
      "tsconfig": "workspace:*",
   }
}
  1. Define .eslintrc.js. Override with your project necessities. This requires eslint-config-custom package.
module.exports = {
  extends: ['custom/next'],
  rules: {
      'react/no-unescaped-entities': 'off',
  },
  ...etc
}
  1. Define tsconfig.json. Override with your project necessities. This requires tsconfig package.
{
   "extends": "tsconfig/nextjs.json",
}
  1. For eslint perfectionist plugin add internalPaths under your package.json file:
{
   "internalPaths": [
      "@",
      "~",
      "@idra"
   ]
}
  1. Bootstrap global config in your pages/_app.tsx file
import { config } from '@edw/base/src'
import { type DrupalConfigRegistry } from '@edw/drupal/src'

import installSite from '@/siteconfig'

Object.assign(
  config as DrupalConfigRegistry,
  installSite(config as DrupalConfigRegistry),
)
  1. Configure pages/_app.tsx:
import { App as BaseApp, DefaultLayout } from '@edw/base/src/components'
import { withAuthInitialSession } from '@edw/drupal/src/hof'
import { SessionProvider } from '@edw/drupal/src/lib/auth'

...etc

export default function App({
  Component,
  pageProps: { initialSession, ...pageProps },
}: AppProps): React.JSX.Element {
  const { breadcrumb, error, menus, node } = pageProps

  return (
    <BaseApp initialAppState={{ breadcrumb, menus, node }} theme={theme()}>
      <SessionProvider initialSession={initialSession}>
         <DefaultLayout
            error={error}
            header={<YourHeader />}
            footer={<YourFooter />}
         >
            <Component {...pageProps} />
         </DefaultLayout>
      </SessionProvider>
    </BaseApp>
  )
}


App.getInitialProps = withAuthInitialSession()
  1. Configure pages/[[...slug]].tsx
import {
  compose,
  withDrupalCommonResources,
  withDrupalNodeResources,
} from '@edw/drupal/src/hof'

...etc

export const getServerSideProps = compose(
  withDrupalCommonResources,
  withDrupalNodeResources,
)()
  1. Define pages/api/auth/[...nextauth].ts apis for next-auth:
import NextAuth from '@edw/drupal/src/lib/auth'
export default NextAuth

Technology stack

  • Nextjs - React-based web development framework
  • Drupal-Next - JS lib to communicate with Drupal backends
  • Antd - React component library and theming engine
  • TanStack/Query - Data management library

Infrastructure stack

  • Storybook - Document and test UI Components
  • Jest - Javascript testing library
  • React - Javascript frontend development library
  • Typescript - Superset of JS, provides static types
  • Turbo Repo - Incremental bundler and build system
  • pnpm - Javascript package manager with support for workspaces
  • Docker - Container-based deployment

Current features:

  • basic Nextjs app, uses "pages" router
  • typescript
  • drupal-next used to integrate with Drupal
  • antd with SSR css file generation
  • custom theme for antd
  • storybook
  • jest tests
  • makefile shortcuts

Architecture

The Base UI library

The packages/base folder has the base library

We follow an Atomic Design approach. See this article for a short overview of Atomic Design

We use the following structure to host our components:

  • atoms: we don't have yet any
  • molecules - basic components
  • blocks - Recipes for bigger components
  • global - Site-wide recipes. Such as basic layout, footer, header, etc.
  • templates - Full pages and layouts

TODO:

jq filters

  • Select a country from a facet
jq '.meta.facets[] | objects | select(.id == "jsonapi_country").terms[] | select(.values.value == "180")'