An open API service indexing awesome lists of open source software.

https://github.com/acquia/next-acms

ACMS with fully or progressively decoupled front-end
https://github.com/acquia/next-acms

Last synced: 12 days ago
JSON representation

ACMS with fully or progressively decoupled front-end

Awesome Lists containing this project

README

        

# Next.js for Acquia CMS

This is a starter template for building a headless site powered by [Acquia CMS](https://www.acquia.com/products/drupal-cloud/acquia-cms) and [Next.js](https://nextjs.org).

This project is built on the following technologies:

- Drupal core
- [Acquia CMS](https://github.com/acquia/acquia_cms) (Drupal distribution)
- [Next.js](https://nextjs.org) (React front-end framework)
- [Next.js for Drupal](https://next-drupal.org) (Tools for integrating Next.js with Drupal)
- [Drupal JSON-API Params](https://github.com/d34dman/drupal-jsonapi-params) (Tools for generating JSON:API queries)
- [Tailwind CSS](https://taiwindcss.com) (Styling library)
- [TypeScript](http://typescriptlang.org)

## Installation (Acquia CMS)

Start by creating a new Acquia CMS project:

_(If you have an existing Acquia CMS project, you can skip this step)_

```
composer create-project acquia/drupal-recommended-project acms-demo
cd acms-demo && ./vendor/bin/acms acms:install
```

From the wizard, select the acquia_cms_headless starter kit and proceed to install Acquia CMS. We recommend using the default
Content Model and the demo content so you can quickly see the content coming through your Next.js application.

**Note**: next-acms requires Acquia CMS 2.0 or later.

Login to Acquia CMS and go to Tour > Get started. From the Headless section on the CMS Dashboard, select the Next.js starter kit and click "Save".
Acquia CMS should print a message with your Node environment variables. Copy these and proceed to the next step.

For more information on Acquia CMS setup please see the [tutorial](https://dev.acquia.com/tutorial/nextjs-acquia-setting-acquia-cms).

## Installation (Next.js)

Run the following command to create a new Next.js project:

```
npx create-next-app -e https://github.com/acquia/next-acms/tree/main/starters/basic-starter
```

This will create a new starter project. [See project structure](#project-structure).

### Connect Drupal

To connect the Next.js site to Drupal, we use [environment variables](https://next-drupal.org/docs/environment-variables).

1. Copy `.env.example` to `.env.local`.
2. Paste in the credentials generated by Acquia CMS and save.

### Start Development Server

To start the Next.js development server, run `yarn dev`. This starts the development server on `http://localhost:3000`.

Visit [http://localhost:3000](http://localhost:3000) to view the headless site.

## Project Structure

This project is a monorepo structure using yarn workspaces. This project has a `packages` directory for next-acms and a `starters` directory for next-acms starter kits.

`starters/basic-starter` has a dependency on `packages/next-acms` which currently has a dependency on `next-drupal`.

```
.
|── node_modules
|── packages
|── next-acms
| |── node_modules
| |── package.json
|── starters
|── basic-starter
├── components
│ ├── layout.tsx
│ ├── media--image.tsx
│ ├── menu--footer.tsx
│ ├── menu--main.tsx
│ ├── node--article.tsx
│ └── node--page.tsx
├── lib
│ └── format-date.ts
├── node_modules
├── pages
│ ├── api
│ │ ├── exit-preview.tsx
│ │ ├── preview.tsx
│ │ └── revalidate.ts
│ ├── _app.tsx
│ ├── [...slug].tsx
│ ├── articles.tsx
│ └── index.tsx
├── public
│ ├── favicon.ico
│ ├── logo.png
│ └── robots.txt
├── styles
│ └── globals.css
├── .env.local
├── next.config.js
├── package.json
├── tailwind.config.js
└── tsconfig.json
|── .gitignore
|── package.json
```

| Path | Description |
| -------------------- | ---------------------------------------------------------------------------------------------------- |
| `components` | Place your React components here. |
| `lib` | For utility or helper functions. |
| `pages` | Learn more about the pages directory [here](https://nextjs.org/docs/basic-features/pages) |
| `public` | For [static files](https://nextjs.org/docs/basic-features/static-file-serving). |
| `styles` | Directory for CSS files. |
| `.env.local` | File for local environment variables. |
| `next.config.js` | [Configuration](https://nextjs.org/docs/api-reference/next.config.js/introduction) file for Next.js. |
| `tailwind.config.js` | [Configuration](https://tailwindcss.com/docs/configuration) file for Tailwind CSS. |

## Routing

The starter ships with static routes for building collection of content: `pages/articles` and an entry point, `[...slug].tsx`, for entity routes.

The `[...slug].tsx` route is called a catch-all route.

When you create an entity on Drupal, and visit the route on your headless site, this is the file that handles data fetching and rendering for the entity.

You can read more about routing in Next.js on the [official docs](https://nextjs.org/docs/routing/introduction).

## Preview Mode

To enable the inline content preview inside Drupal, we need to configure a site resolver for the content type.

_A *site resolver* tells Drupal how to resolve the preview URL for an entity._

### Configure preview mode for article

1. Visit _/admin/config/services/next/entity-types_
2. Click **Configure entity type**
3. Select **Article** from the the entity type list
4. Select **Site selector** as the **Site resolver**
5. Select the Next.js site under **Next.js sites**
6. Click **Save**

If you visit an article from the Drupal administration, you should now see an inline preview inside an iframe.

Repeat the same steps for other content types.

## Data Fetching

To build pages from Drupal content, data is fetch in `getStaticProps` and passed to the component.

See the [documentation](https://next-drupal.org/docs/data-fetching) on data fetching in next-drupal.

### Adding a new entity type.

To create headless pages for a new content type:

1. Start by creating the content type, say `News`, on Drupal.
- Define the fields: `title`, `field_teaser` and `body`.
- Add a path alias for the content type: `news/[node:title]`.
2. On the Next.js site, edit `[...slug].tsx` to fetch news from Drupal.
3. Add `node--news` to `CONTENT_TYPES`:

```diff
// List of all the entity types handled by this route.
const CONTENT_TYPES = [
"node--page",
"node--article",
"node--event",
"node--person",
"node--place",
+ "node--news",
]
```

4. In `getStaticProps`, build the query for fetching the `node--news` with the fields:

```diff
+ if (type === "node--news") {
+ params
+ .addFields("node--news", ["title", "path", "field_teaser", "body])
+ }
```

5. Add a news on Drupal and visit the path on your Next.js site: `http://localhost:3000/news/title-of-news`.
6. If you add a `console.log(node)` in the `NodePage` component you should see the `node--news` data.

```diff
export default function NodePage({ node, menus }: NodePageProps) {
if (!node) return null

+ console.log(node)
```

7. You can now use this `node--news` object to create the `` component.

```diff
export default function NodePage({ node, menus }: NodePageProps) {
if (!node) return null

return (

{node.type === "node--page" && }
{node.type === "node--article" && }
{node.type === "node--event" && }
{node.type === "node--person" && }
{node.type === "node--place" && }
+ {node.type === "node--news" && }

)
}
```

## Reporting a Security Issue

If you believe you have found a security vulnerability in an Acquia product or service, we encourage you to responsibly disclose this and not open a public issue. We will investigate all legitimate reports. Please email the details to our security team at [email protected].

https://www.acquia.com/why-acquia/industries/security