Coder Social home page Coder Social logo

headless's Introduction

Next.js for Acquia CMS

This is a starter template for building a headless site powered by Acquia CMS and Next.js.

This project is built on the following technologies:

Installation (Acquia CMS)

Create Acquia CMS project

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.

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.

Connect Drupal

To connect the Next.js site to Drupal, we use 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 to view the headless site.

Project Structure

.
├── components
│   ├── layout.tsx
│   ├── media--image.tsx
│   ├── menu--footer.tsx
│   ├── menu--main.tsx
│   ├── node--article.tsx
│   └── node--page.tsx
├── lib
│   └── format-date.ts
├── 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
Path Description
components Place your React components here.
lib For utility or helper functions.
pages Learn more about the pages directory here
public For static files.
styles Directory for CSS files.
.env.local File for local environment variables.
next.config.js Configuration file for Next.js.
tailwind.config.js 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.

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 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:
// 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",
]
  1. In getStaticProps, build the query for fetching the node--news with the fields:
+ if (type === "node--news") {
+ 	params
+ 		.addFields("node--news", ["title", "path", "field_teaser", "body])
+ }
  1. Add a news on Drupal and visit the path on your Next.js site: http://localhost:3000/news/title-of-news.
  2. If you add a console.log(node) in the NodePage component you should see the node--news data.
export default function NodePage({ node, menus }: NodePageProps) {
  if (!node) return null

+ console.log(node)
  1. You can now use this node--news object to create the <NodeNews /> component.
export default function NodePage({ node, menus }: NodePageProps) {
  if (!node) return null

  return (
    <Layout title={node.title} menus={menus}>
      {node.type === "node--page" && <NodeBasicPage node={node} />}
      {node.type === "node--article" && <NodeArticle node={node} />}
      {node.type === "node--event" && <NodeEvent node={node} />}
      {node.type === "node--person" && <NodePerson node={node} />}
      {node.type === "node--place" && <NodePlace node={node} />}
+     {node.type === "node--news" && <NodeNews node={node} />}
    </Layout>
  )
}

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.