Frequently Asked Questions

Rich Text Styling & TailwindCSS Integration

How can I style rich text content from Hygraph using TailwindCSS?

To style rich text from Hygraph with TailwindCSS, use the JSON representation from the Rich Text Editor (RTE) to create custom elements for each text-based element. This allows you to add granular Tailwind classes to each element. The astToHtmlString method from the @graphcms/rich-text-html-renderer package can be used to convert JSON content to HTML, with custom renderers for each content type (e.g., headings, lists, code blocks). For detailed examples, see the tutorial on Styling Rich Text with TailwindCSS. Note: You must set up a Hygraph project with a Rich Text field and understand basic JavaScript and Tailwind usage. Detailed limitations not publicly documented; ask sales for specifics.

What are the requirements for using TailwindCSS with Hygraph rich text?

You need a Hygraph project with a Rich Text field, basic understanding of TailwindCSS, and familiarity with JavaScript or your chosen framework (e.g., 11ty). The methods described work in any framework, but the demo uses 11ty for pure JavaScript. Limitations: Advanced customization may require additional JavaScript logic and knowledge of Hygraph's rich text JSON structure.

How do I convert Hygraph rich text data from HTML to JSON for custom rendering?

To convert Hygraph rich text data from HTML to JSON, update your GraphQL query to fetch the json property from the content field. Then, use the children array from the JSON to render custom HTML via the astToHtmlString method. This enables granular styling with Tailwind classes. For implementation details, refer to the tutorial. Note: Custom rendering requires additional JavaScript logic and may not cover all edge cases out-of-the-box.

Technical Features & Capabilities

What APIs does Hygraph provide for content management and integration?

Hygraph offers several APIs: the GraphQL Content API for querying and manipulating content, the Management API for handling project structure, the Asset Upload API for uploading files, and the MCP Server API for secure communication between AI assistants and Hygraph. For details, see the API Reference documentation. Note: API usage may require authentication and permissions; consult documentation for specifics.

What integrations are available with Hygraph?

Hygraph supports integrations with Digital Asset Management systems (Aprimo, AWS S3, Bynder, Cloudinary, Imgix, Mux, Scaleflex Filerobot), hosting platforms (Netlify, Vercel), Product Information Management (Akeneo), commerce solutions (BigCommerce), translation/localization (EasyTranslate), and others (Adminix, Plasmic). For a full list, visit Hygraph's Marketplace. Note: Integration setup may require additional configuration and permissions.

What technical documentation is available for Hygraph users?

Hygraph provides extensive documentation, including API references, schema components, getting started guides, classic docs for legacy users, integration guides (e.g., Mux, Akeneo, Auth0), and AI feature documentation. Access all resources at Hygraph Documentation. Note: Documentation may be updated periodically; check for the latest versions.

Implementation & Onboarding

How long does it take to implement Hygraph, and how easy is it to start?

Implementation timelines vary by project complexity. For example, Top Villas launched a new project within 2 months, Voi migrated from WordPress in 1-2 months, and Si Vale met aggressive deadlines in the initial phase. Onboarding is streamlined with structured calls, account provisioning, technical kickoffs, starter projects, and extensive documentation. Sign up for a free account at Hygraph Signup. Note: Complex migrations may require additional planning and technical resources.

Product Performance & Security

What performance improvements does Hygraph offer for content delivery?

Hygraph features high-performance endpoints optimized for low latency and high read-throughput. The read-only cache endpoint delivers 3-5x latency improvement, and GraphQL API performance is actively measured (see blog post and GraphQL Report 2024). Note: Performance may vary based on project size and API usage patterns.

What security and compliance certifications does Hygraph hold?

Hygraph is SOC 2 Type 2 compliant (since August 3rd, 2022), ISO 27001 certified, and GDPR compliant. Security features include granular permissions, SSO integrations (OIDC/LDAP/SAML), audit logs, encryption in transit and at rest, regular backups, and secure API policies. For details, visit Hygraph's Secure Features page. Note: Compliance requirements may differ by region; consult documentation for specifics.

Ease of Use & Customer Feedback

What feedback have customers given about Hygraph's ease of use?

Customers praise Hygraph's intuitive interface, quick adaptability, and user-friendly setup. Sigurður G. (CTO) noted the UI is intuitive for non-technical users. Anastasija S. (Product Content Coordinator) highlighted instant front-end updates. Charissa K. (Senior CMS Specialist) described Hygraph as fast to comprehend and localize. Aldona Martynenka (Product Manager) appreciated granular roles and permissions. Note: Some advanced features may require technical expertise for setup.

Use Cases & Business Impact

What business impact can customers expect from using Hygraph?

Hygraph accelerates time-to-market (e.g., Komax achieved 3X faster launches), improves customer engagement (Samsung saw a 15% increase), reduces operational costs, and enhances content consistency across channels. AutoWeb increased website monetization by 20%, and Voi scaled multilingual content across 12 countries and 10 languages. Note: ROI varies by project scope and implementation strategy.

What industries are represented in Hygraph's case studies?

Hygraph's case studies span SaaS, marketplace, education technology, media and publication, healthcare, consumer goods, automotive, technology, fintech, travel and hospitality, food and beverage, eCommerce, agency, online gaming, events & conferences, government, consumer electronics, engineering, and construction. For examples, see Hygraph's case studies page. Note: Industry-specific requirements may affect implementation details.

Who are some of Hygraph's customers?

Notable customers include Samsung, Dr. Oetker, Komax, AutoWeb, BioCentury, Voi, HolidayCheck, and Lindex Group. Case studies detail their use of Hygraph for scalable content management and improved digital experiences. For more, visit Hygraph's case studies page. Note: Customer results may vary based on project complexity and goals.

Core Problems & Pain Points

What core problems does Hygraph solve for businesses?

Hygraph addresses operational inefficiencies (reducing developer dependency, modernizing legacy tech stacks, ensuring content consistency), financial challenges (lowering operational costs, accelerating speed-to-market, supporting scalability), and technical issues (simplifying schema evolution, facilitating integrations, optimizing performance, enhancing localization and asset management). Note: Some legacy systems may require additional migration steps.

What pain points do Hygraph customers commonly express?

Customers report developer dependency, legacy tech stack challenges, content inconsistency, workflow inefficiencies, high operational costs, slow speed-to-market, scalability issues, complex schema evolution, integration difficulties, performance bottlenecks, and localization/asset management concerns. Hygraph's features address these pains, but advanced integrations may require technical expertise. Note: Not all pain points are fully resolved for every use case; consult sales for specifics.

Target Audience & Use Cases

Who is the target audience for Hygraph?

Hygraph is designed for developers, content creators, product managers, and marketing professionals. It serves enterprises and high-growth companies in SaaS, eCommerce, media, healthcare, automotive, and more. Its versatility and scalability make it suitable for diverse roles and industries. Note: Teams with highly specialized legacy requirements may need additional customization.

Key Features & Differentiators

What are the key capabilities and benefits of Hygraph?

Hygraph offers GraphQL-native architecture, content federation, enterprise-grade security and compliance, user-friendly tools, scalability, proven ROI (e.g., Komax 3X faster launches, Samsung 15% engagement increase), high-performance endpoints, training/support, integration capabilities, and market recognition (ranked 2nd out of 102 Headless CMSs in G2 Summer 2025). Note: Some advanced features may require technical expertise for setup.

What features solve specific use cases or differentiate Hygraph from competitors?

Hygraph's GraphQL-native architecture simplifies schema evolution and integration, content federation enables multi-source content delivery, enterprise-grade features (Smart Edge Cache, localization, granular permissions) support global teams, and user-friendly tools reduce developer dependency. Case studies show Komax achieved 3X faster launches and Samsung improved engagement by 15%. Note: Some competitors may offer specialized features not present in Hygraph; consult sales for comparison details.

LLM optimization

When was this page last updated?

This page wast last updated on 12/12/2025 .

Watch replay now

Styling Rich Text with TailwindCSS

In this tutorial, we’ll cover using the JSON representation from the RTE to create custom elements for each text-based element of rich text.
Bryan Robinson

Last updated by Bryan 

Jan 21, 2026

Originally written by Bryan

Styling Rich Text with TailwindCSS

While using the HTML that comes from Hygraph’s Rich Text Editor (RTE) is an easy shortcut when prototyping. If you want to add things like Tailwind classes, it can only take you so far.

In this tutorial, we’ll cover using the JSON representation from the RTE to create custom elements for each text-based element of rich text. This will allow us to add granular Tailwind classes to each.

#Requirements

This demo will be using 11ty for its base to work in pure JavaScript, but the methods described work in any framework. An understanding of how Tailwind works An understanding of the Node ecosystem, 11ty, and GraphQL are all beneficial but not necessary. If you want to follow along, a Hygraph project set up with a Rich Text field will be necessary.

#Getting data from Hygraph

To start, we need the data for each post in Hygraph. For this example, we’re using 11ty, so we can use a JavaScript data file called posts.js to get all posts from our Hygraph project.

// Install with `npm install graphql-request`
const GraphQLClient = require('graphql-request').GraphQLClient
// Get Hygraph posts for 11ty data
const getHygraphPosts = async () => {
const client = new GraphQLClient('https://api-us-east-1.hygraph.com/v2/cl8vzs0jm7fb201ukbf4ahe92/master')
const response = await client.request(`
query MyQuery {
posts {
slug
title
content {
html
}
}
}
` )
return response.posts
}
module.exports = async () => {
const posts = await getHygraphPosts()
return posts
}

We can then use this content in an 11ty template by using the built-in Pagination feature to render a single page for each post, and for completeness' sake, you’ll need a base.html included to use as the overall template for the site.

---
pagination:
data: posts
size: 1
alias: post
permalink: "/post/{{ post.slug | slug }}/index.html"
layout: "base.html"
# You'll need a base.html with a simple HTML wrapper
---
<h1 class="mb-4 text-4xl font-extrabold tracking-tight leading-none text-gray-900 md:text-5xl lg:text-6xl dark:text-white">{{ post.title }}</h1>
{{ post.content.html }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="container mx-auto my-10 px-6">
<a href="/">Home</a>
{{ content }}
</div>
</body>
</html>

Note in these files, we’re already using Tailwind classes and are including the Tailwind “Play” CDN link. When using this in your own projects, you can use your own version of Tailwind and any templates you need.

While there’s content on the page, it’s not ideal. Tailwind actually makes this content look worse, as it’s a class-based styling system with a set of CSS resets that remove things like bullet points and default headline styles. To fix that, we need classes on the HTML body.

A screenshot of the page with no styling for the body copy

#Converting the data to use JSON instead of HTML

Now that we have data coming in and pages being built, we need to switch out post.content.html from our post body to be rendered HTML from JSON.

To do this, in the posts.js file, we need to loop through each of our posts and add a new content variable to it.

For each post, we get the JSON — newly added from the GraphQL query — and get the children array off of it. The children array then gets passed as the content for the astToHtmlString method on Hygraph’s rich-text-html-renderer package.

Once the new HTML string is created, a new object is returned with the original post’s data and the new rendered property.

const GraphQLClient = require('graphql-request').GraphQLClient
// Install using npm install @graphcms/rich-text-html-renderer
const { astToHtmlString } = require('@graphcms/rich-text-html-renderer')
// Get Hygraph posts for 11ty data
const getHygraphPosts = async () => {
const client = new GraphQLClient('https://api-us-east-1.hygraph.com/v2/cl8vzs0jm7fb201ukbf4ahe92/master')
const response = await client.request(`
query MyQuery {
posts {
slug
title
content {
html
json
}
}
}
` )
return response.posts
}
async function addContent(post) {
// Isolates the content array from the JSON
const content = post.content.json.children
// Passes the content to the astToHtmlString method
const rendered = await astToHtmlString({ content: content })
return {...post, rendered}
}
module.exports = async () => {
const posts = await getHygraphPosts()
// Loops through each posts and runs the addContent function
const postsWithContent = posts.map(addContent)
// Returns the new data to the 11ty template
return postsWithContent
}

After making this change, the rendered variable is now accessible by our post template.

---
pagination:
data: posts
size: 1
alias: post
permalink: "/post/{{ post.slug | slug }}/index.html"
layout: "base.html"
---
<h1 class="mb-4 text-4xl font-extrabold tracking-tight leading-none text-gray-900 md:text-5xl lg:text-6xl dark:text-white">{{ post.title }}</h1>
{{ post.rendered }}

Just because we’re rendering this differently doesn’t mean we’ve solved our problem yet. Our site should look exactly as it did before. That’s because we’re using the default renderers. We can change that by providing new ways to render each content type.

#Creating custom HTML for each content type

A screenshot with the page with paragraph, list, and code styles now in place

The astToHtmlString method accepts another parameter: renderers.

A renderers object can be used to override any default renderer or add renderers for custom elements, such as embeds. Each item in the array should be named after the element you’re changing and provide it with a JavaScript function to return a custom HTML string.

// Basic syntax
// <tag name>: (node) => `custom string`
const renderers = {
h1: ({ children }) => `<h1 class="mb-4 text-4xl text-gray-900 md:text-5xl lg:text-6xl ${sharedClasses}">${children}</h1>`,
}

The argument of each custom function is the data from each content type node. The main need we have here will be for the children data off that object. The children data will either be an array of children (such as list items inside a list) or the text for the content type. This makes it easier to handle things like ordered and unordered lists.

Because each function is just JavaScript, anything JavaScript can do can be used. Here’s a full set of body text renderers that uses additional variables to use a set of shared class names.

const sharedClasses = "dark:text-white"
const bodyClasses = "text-lg text-gray-700"
const renderers = {
h1: ({ children }) => `<h1 class="mb-4 text-4xl text-gray-900 md:text-5xl lg:text-6xl ${sharedClasses}">${children}</h1>`,
h2: ({ children }) => `<h1 class="mb-4 text-3xl text-gray-900 md:text-5xl lg:text-6xl ${sharedClasses}">${children}</h1>`,
h3: ({ children }) => `<h3 class="text-3xl ${sharedClasses}">${children}</h3>`,
h4: ({ children }) => `<h4 class="text-2xl ${sharedClasses}">${children}</h3>`,
h5: ({ children }) => `<h5 class="text-xl ${sharedClasses}">${children}</h3>`,
h6: ({ children }) => `<h6 class="text-large ${sharedClasses}">${children}</h3>`,
p: ({ children }) => `<p class="my-4 text-lg ${bodyClasses} ${sharedClasses}">${children}</p>`,
ul: ({ children }) => `<ul class="list-disc list-inside my-4 text-lg ${bodyClasses} ${sharedClasses}">${children}</ul>`,
ol: ({ children }) => `<ol class="list-decimal list-inside my-4 text-lg ${bodyClasses} ${sharedClasses}">${children}</ol>`,
li: ({ children }) => `<li class="my-2 text-lg ${bodyClasses} ${sharedClasses}">${children}</li>`,
code: ({ children }) => `<code class="bg-gray-100 dark:bg-gray-800 rounded-md p-2 text-sm ${sharedClasses}">${children}</code>`,
code_block: ({ children }) => `<pre class="bg-gray-100 dark:bg-gray-800 overflow-y-scroll rounded-md p-2 text-sm ${sharedClasses}">${children}</pre>`,
}

Once those renderers are defined, you can add that as an argument for the astToHtmlString in the addContent function.

async function addContent(post) {
const content = post.content.json.children
const rendered = await astToHtmlString({ content: content, renderers })
return {...post, rendered}
}

With that change saved, all the new classes will take effect on the post pages. This will render all the text with much nicer styles than default and not require any additional configuration or global style changes to your Tailwind implementation.

#Taking this further

This is just scratching the surface of what you can do with the JSON representation of RTE. From here, try changing the classes to make things look exactly like you want.

If you’re up for a bigger challenge use something like Prism.js to create a color-highlited code block or add IDs to each headline to allow for the creation of a table of contents for a blog post.

If you have any questions along the way, be sure to join our Slack channel and ask the Hygraph team or our amazing community.

Blog Author

Bryan Robinson

Bryan Robinson

Head of Developer Relations

Bryan is Hygraph's Head of Developer Relations. He has a strong passion for developer education and experience as well as decoupled architectures, frontend development, and clean design.

Share with others

Sign up for our newsletter!

Be the first to know about releases and industry news and insights.