Skip to main content

Retrieving Content from a Custom Content Type Using useContent

Introduction

When working with custom content types in Drupal and attempting to retrieve their content using the useContent hook, you might encounter an error like:

"message": "Fragment \"NodeLandingPage\" is never used."

This error occurs because the GraphQL fragment you defined for your custom content type (NodeLandingPage in this case) is not being utilized in any query. To resolve this, you need to properly include your custom fragment within the base fragment used by your application.

Solution Overview

tip

To retrieve content from a custom content type using useContent, follow these steps:

  1. Define a Fragment for Your Custom Content Type
  2. Include Your Custom Fragment within the Base Node Fragment
  3. Update Your CMS Configuration
  4. Use the useContent Hook to Fetch Your Content

Step-by-Step Guide

1. Define a Fragment for Your Custom Content Type

Start by defining a GraphQL fragment for your custom content type. For example, for a content type named LandingPage:

const NodeLandingPage = gql`
fragment NodeLandingPage on Entity {
... on NodeLandingPage {
id
title: label
// Include other fields specific to your content type
fieldHeroTitle
fieldHeroSubtitle
fieldHeroImage {
url
alt
}
}
}
`;

2. Include Your Custom Fragment within the Base Node Fragment

Your custom fragment needs to be included in the base fragment used for nodes in your application:

const NodeArticle = gql`
fragment NodeArticle on Entity {
... on NodeArticle {
id
uuid
title: label
body
status
// Other existing fields
}
// Include your custom content type fragment
... on NodeLandingPage {
...NodeLandingPage
}
}
${NodeLandingPage}
`;

3. Update Your CMS Configuration

In your CMS configuration, update the queries object to include the updated base fragment:

const config = {
drupalUrl: `${process.env.NEXT_PUBLIC_DRUPAL_URL}`,
queries: {
Nodes: {
NodeArticle, // This now includes the NodeLandingPage fragment
},
},
};

4. Use the useContent Hook to Fetch Your Content

Now, you can use the useContent hook to retrieve content from your custom content type:

import { useContent } from '@your-org/cms-integration';

const { data, loading, error } = useContent({
type: 'node--landing_page', // Use the machine name of your content type
id: 'your-node-id',
});

// Now you can use 'data' to access your content
console.log(data.title); // Accessing the title
console.log(data.fieldHeroTitle); // Accessing a custom field

Specific Example: LandingPage Content Type

Here's a more comprehensive example using the LandingPage content type:

// Define your custom fragment
const NodeLandingPage = gql`
fragment NodeLandingPage on Entity {
... on NodeLandingPage {
id
title: label
fieldHeroTitle
fieldHeroSubtitle
fieldHeroImage {
url
alt
}
fieldSections {
... on ParagraphTextWithImage {
id
fieldTitle
fieldBody
fieldImage {
url
alt
}
}
... on ParagraphCallToAction {
id
fieldTitle
fieldLinkText
fieldLink {
url
title
}
}
}
}
}
`;

// Update the base fragment to include your custom fragment
const NodeArticle = gql`
fragment NodeArticle on Entity {
... on NodeArticle {
id
uuid
title: label
body
status
}
... on NodeLandingPage {
...NodeLandingPage
}
}
${NodeLandingPage}
`;

// Update your CMS configuration
const config = {
drupalUrl: process.env.NEXT_PUBLIC_DRUPAL_URL,
queries: {
Nodes: {
NodeArticle,
},
},
};

// Use the 'useContent' hook to fetch your custom content
const { data, loading, error } = useContent({
type: 'node--landing_page',
id: 'your-landing-page-id',
});

// Accessing the data
if (data) {
console.log(data.title); // Landing page title
console.log(data.fieldHeroTitle); // Hero title
console.log(data.fieldSections); // Array of sections (paragraphs)
}

Understanding the Error

The "Fragment is never used" error occurs because GraphQL requires all defined fragments to be used in a query. When you define a fragment (like NodeLandingPage) but don't include it in any query, GraphQL throws this error.

Our solution prevents this by:

  1. Defining the custom fragment (NodeLandingPage)
  2. Including it within a base fragment that's already being used (NodeArticle)
  3. Using the spread operator (...NodeLandingPage) to include all fields from the custom fragment
  4. Explicitly including the custom fragment in the base fragment definition (${NodeLandingPage})

This approach ensures that the custom fragment is always included in queries that use the base fragment, thus preventing the "never used" error.

Troubleshooting

If you're still encountering issues:

  1. Check Fragment Names: Ensure that your fragment names match exactly in all places they're used.
  2. Verify Field Names: Double-check that all field names in your fragments match the field names in your Drupal content type.
  3. GraphQL Query Inspection: Use GraphQL tools (like GraphiQL) to inspect and test your queries directly against your Drupal backend.
  4. Clear Caches: Clear both your Drupal and Next.js caches after making changes to your GraphQL schema or fragments.
  5. Check Content Type Machine Names: Ensure you're using the correct machine name for your content type in the useContent hook (e.g., node--landing_page for a LandingPage content type).
warning

If problems persist, review your Drupal GraphQL schema and ensure that all custom fields are properly exposed.

Conclusion

By following this guide, you should be able to successfully retrieve content from custom content types in Drupal using the useContent hook, without encountering the "Fragment is never used" error. Remember to adjust the fragment fields based on your specific content type structure.

info

Always ensure that your GraphQL queries are correctly structured and that all fragments are appropriately included to avoid runtime errors. Regularly test your queries against your Drupal backend to catch any discrepancies early in the development process.