Sitelet https://github.com/contentful/rich-text-renderer-java
Skip to content

Join Contentful Community Slack   Join Contentful Community Forum

rich-text-renderer-java - Rich Text Rendering for Contentful on the JVM

Java library for rendering Contentful Rich Text fields. It helps you easily render rich text stored in Contentful using Java, targeting both plain JVM applications (HTML output) and Android (Spannables or native Views).

This repository is actively maintained   JitPack

What is Contentful?

Contentful provides content infrastructure for digital teams to power websites, apps, and devices. Unlike a CMS, Contentful was built to integrate with the modern software stack. It offers a central hub for structured content, powerful management and delivery APIs, and a customizable web app that enable developers and content creators to ship their products faster.

Table of contents

Core Features

  • Takes the rich text node tree produced by contentful.java (CDARichDocument and friends) and renders it into a representation that's easy to use in your own project.
  • html module: converts rich text into an HTML string, suitable for any JVM application (web backends, CLI tools, etc).
  • android module: converts rich text into either CharSequence/Spannable output for TextView, or native Android View hierarchies — your choice.
  • A shared core module defines the Processor/Renderer/RenderabilityChecker pattern used by both the html and android modules, and is dependency-free of either.
  • Fully extensible: add a new Renderer to a Processor via .addRenderer(…), or replace a default one via .overrideRenderer(…), without forking the library.
  • Simplifier utilities to clean up a rich text graph before rendering — for example removing empty nodes or nodes nested beyond a given depth (RemoveToDeepNesting), useful for capping Android rendering time on deeply nested documents.
  • Ships as three independently versioned JitPack artifacts (core, html, android) so you only pull in what you need.

Getting started

Requirements

Requirement Version
Java 17
Android (for the android module) compileSdk 35, minSdk 23

This library depends on contentful.java for the CDARichDocument node model that it renders.

Installation

Artifacts are distributed via JitPack. Add the JitPack repository, then depend on the module(s) you need:

  • Gradle
allprojects {
  repositories {
    // …
    maven { url 'https://jitpack.io' }
  }
}
dependencies {
  // …
  // JVM / server (HTML output):
  implementation 'com.contentful.java:java-sdk:10.6.1'
  implementation 'com.github.contentful.rich-text-renderer-java:html:2.4.1'
}
dependencies {
  // Android: from 2.4.1 the android artifact brings core and java-sdk (without okhttp-jvm).
  implementation 'com.github.contentful.rich-text-renderer-java:android:2.4.1'

  // If you also declare java-sdk yourself, exclude okhttp-jvm. Otherwise the build fails with
  // "Duplicate class okhttp3.…" against okhttp-android:
  implementation('com.contentful.java:java-sdk:10.6.1') {
    exclude group: 'com.squareup.okhttp3', module: 'okhttp-jvm'
  }
}

2.4.1 notes for Android: the minimum SDK is 23 (it was 21 up to 2.3.x). Links in rich text are opened only for http, https, mailto, tel and sms; other schemes such as javascript: or intent: cannot navigate. Don't use 2.4.0: it has an unprotected link path and a list-rendering crash, both fixed in 2.4.1. The default embedded-image provider returns a placeholder on the main thread. Render off the main thread for downloads (bounded by a 3-second timeout per image), or supply a custom BitmapProvider that uses cached images.

2.4.1 notes for the HTML module: attribute values are now HTML-escaped (for example & in a link becomes &amp;), and links with a disallowed scheme (javascript:, data:, …) are rendered as <a> without an href. Relative links (/about, #top) are unchanged.

  • Maven
<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>
<dependency>
    <groupId>com.contentful.java</groupId>
    <artifactId>java-sdk</artifactId>
    <version>10.6.1</version>
</dependency>
<dependency>
    <groupId>com.github.contentful.rich-text-renderer-java</groupId>
    <artifactId>html</artifactId>
    <version>2.4.1</version>
</dependency>

Using the SDK

Both the html and android modules start the same way: fetch an entry containing a rich text field with the base contentful.java SDK, then extract the CDARichDocument:

final CDAClient client = CDAClient.builder()
    .setSpace(SPACE_ID)
    .setToken(TOKEN)
    .build();

final CDAEntry entry = client
    .fetch(CDAEntry.class)
    .one(ENTRY_ID);

final CDARichDocument node = entry.getField(FIELD_ID);

If your rich text data comes from an external tool (for example, a JavaScript library) rather than directly through this SDK, build a CDARichDocument from plain JSON using GSON:

private final Gson gson = new Gson();
Type type = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> jsonMap = gson.fromJson(json, type);
final CDARichDocument node = RichTextFactory.resolveRichNode(jsonMap);

Rendering to HTML

Use the html module to convert the node tree into an HTML string:

final HtmlProcessor processor = new HtmlProcessor();
final HtmlContext context = new HtmlContext();
final String html = processor.process(context, node);

See the html module README for the full guide, including custom renderers.

Rendering on Android

Use the android module to convert the node tree into either CharSequence/Spannable output, or native Views:

final AndroidProcessor<CharSequence> sequenceProcessor = AndroidProcessor.creatingCharSequences();
// or
final AndroidProcessor<View> viewProcessor = AndroidProcessor.creatingNativeViews();

final AndroidContext context = new AndroidContext(activity.getContext());

final CharSequence result = sequenceProcessor.process(context, node);
// or
final View result = viewProcessor.process(context, node);

See the android module README for the full guide, including rendering embedded entries/assets and hyperlinks, and performance advice for deeply nested documents.

Extending with custom renderers

Extend the core functionality by adding a new Renderer to a Processor. A Processor holds a list of renderers; each one knows how to render one kind of rich text node. Adding a renderer with .addRenderer(…) appends it to the end of the list (lowest priority, used as a fallback); .overrideRenderer(…) prepends it (checked first, taking priority over the built-in renderer for that node type):

processor.addRenderer(
    (context, node) -> true, // Checker: does the renderer need to be invoked?
    (context, node) -> node.toString() // Renderer: renders the specific node.
)

Extending is especially important if you plan on rendering embedded or hyperlink rich text nodes: this library cannot know your content model in advance, so it never ships a default renderer for those node types. Always provide your own renderer for embedded entries, embedded assets, and hyperlinks.

We are always looking for feedback — feel free to create an issue.

Documentation & References

This library is a companion to contentful.java; consult its README for details on CDAClient, fetching entries, and the CDARichDocument node model this library renders. Every released change is recorded in the module-level source and JitPack release history.

Reach out to us

Have questions about how to use this library?

  • Reach out to our community forum: Contentful Community Forum
  • Jump into our community slack channel: Contentful Community Slack

You found a bug or want to propose a feature?

  • File an issue here on GitHub: File an issue. Make sure to remove any credential from your code before sharing it.

Get involved

PRs Welcome

We appreciate any help on our repositories. See CONTRIBUTING.md for the full contributor workflow.

Development setup

This is a multi-module Gradle project (core, html, android, android_sample). Use the included Gradle wrapper — do not install Gradle separately:

git clone git@github.com:contentful/rich-text-renderer-java.git
cd rich-text-renderer-java

# Build all modules.
./gradlew build

# Run all tests.
./gradlew test

# Build or test a specific module.
./gradlew :core:build
./gradlew :html:test
./gradlew :android:test

License

This repository is published under the MIT license.

Code of Conduct

We want to provide a safe, inclusive, welcoming, and harassment-free space and experience for all participants, regardless of gender identity and expression, sexual orientation, disability, physical appearance, socioeconomic status, body size, ethnicity, nationality, level of experience, age, religion (or lack thereof), or other identity markers.

Read our full Code of Conduct.

Documentation & Agent Context

Document What it covers
ARCHITECTURE.md Internal module structure, data flow, key dependencies, extension model
CONTRIBUTING.md Build setup, test commands, commit conventions, release process
docs/ADRs/ Why key decisions were made (distribution, module structure, renderer pattern)
AGENTS.md Agent-first context directory — sharp edges, invariants, quick reference

Integration Context

Upstream (this repo consumes):

  • contentful.java SDK (com.contentful.java:java-sdk) — provides the CDARichNode type hierarchy

Downstream (consumes this repo):

  • JVM and Android applications that render Contentful Rich Text fields
  • Distributed via JitPack

About

Rich Text Renderer for Java

Resources

Code of conduct

Contributing

Security policy

Stars

9 stars

Watchers

5 watching

Forks

Releases

Contributors

Languages