contentful/rich-text
PHP library for parsing and rendering Contentful Rich Text fields. Parses localized rich text JSON into node objects, resolves linked assets/entries via a link resolver, and renders nodes to output with a simple Renderer API. Requires PHP 7.2+ / 8.0+.
richText field type). It aligns with Laravel’s dependency injection and service container patterns, especially when combined with Laravel’s templating engines (Blade, Twig, or Plates).NodeInterface, NodeRendererInterface) is a clean abstraction for handling nested content structures, making it extensible for custom content types (e.g., tables, embeds, or custom blocks).parseLocalized(), avoiding bugs with embedded assets/entries in mismatched locales (a common pitfall in headless CMS setups).composer require contentful/rich-text, with autoloader compatibility for Laravel’s PSR-4 standards.TwigExtension/PlatesExtension, enabling seamless rich-text rendering in views.Contentful\RichText\Parser to the container).NodeRendererInterface enables deep customization (e.g., wrapping headings in Laravel-specific classes, integrating with Laravel’s HTML helpers like Str::limit()).| Risk Area | Mitigation Strategy |
|---|---|
| Breaking Changes | Monitor ParserInterface/RendererInterface for major version bumps (e.g., 4.0.0 dropped PHP7). Use ^4.0 in composer.json to auto-update. |
| Locale Mismatches | Enforce parseLocalized($data, $locale) in all parsers (per AGENTS.md). |
| Embedded Asset Links | Opt-in EmbeddedImage renderer via $renderer->enableEmbeddedImageRenderer(true) to avoid unexpected behavior. |
| Performance | Benchmark parsing/rendering of large rich-text blocks (e.g., 100+ nodes) in Laravel’s request lifecycle. |
| Template Escaping | Use {{ $richText->render() }} in Blade/Twig with ` |
return $this->richTextField->parseLocalized($this->richTextField->getData(), app()->getLocale());CatchAll renderer or throw exceptions?AppServiceProvider:
public function register(): void
{
$this->app->singleton(Contentful\RichText\Parser::class, fn() =>
new Contentful\RichText\Parser($this->app->make(Contentful\RichText\LinkResolver::class))
);
$this->app->singleton(Contentful\RichText\Renderer::class, fn() =>
(new Contentful\RichText\Renderer())->pushNodeRenderer(new CustomHeadingRenderer())
);
}
RichText facade for concise syntax:
use Illuminate\Support\Facades\Facade;
class RichText extends Facade { protected static function getFacadeAccessor() => 'richText.renderer'; }
Usage: RichText::render($node).TwigExtension via a custom Blade directive or inline PHP:
{!! RichText::render($entry->richTextField) !!}
rich_text_render_collection).contentful/php-sdk for fetching rich-text data:
$client = new \Contentful\Client();
$entry = $client->getEntry($entryId);
$parsed = app(Contentful\RichText\Parser::class)->parseLocalized($entry->fields->richText, app()->getLocale());
NodeRendererInterface for custom nodes (e.g., EmbeddedVideo, CalloutBlock).EmbeddedEntryBlock to fetch additional metadata from Contentful.RichText::render().Cache::remember()).| Component | Compatibility Notes |
|---|---|
| Laravel Versions | Tested with Laravel 9+ (PHP 8.0+). Avoid PHP 7.x due to package’s PHP 8.0+ requirement. |
| Contentful SDK | Ensure contentful/php-sdk version matches the rich-text field structure (e.g., v10+). |
| Templating Engines | Blade: Use {{ !! }} for raw HTML output. Twig/Plates: Use provided extensions. |
| Custom Content Models | Extend NodeRendererInterface for unsupported Contentful field types (e.g., custom blocks). |
AppServiceProvider.LinkResolver for resolving embedded assets/entries (e.g., via Contentful’s API client).FormRequest or controller).$node = app(Contentful\RichText\Parser::class)->parseLocalized(
$entry->fields->richText,
request()->locale
);
<div class="content">
{!! RichText::render($node) !!}
</div>
NodeRendererInterface for custom logic (e.g., analytics tracking, A/B testing).app(Contentful\RichText\Renderer::class)->pushNodeRenderer(new AnalyticsHeadingRenderer());
contentful/rich-text for breaking changes (e.g., locale support in 4.0.0).composer why-not contentful/rich-text:4.0.0 to check compatibility.NodeRenderer implementations in a README.md or ADR.config/rich-text.php).Parser::parse() → parseLocalized()) via static analysis tools like PHPStan.var_dump($node->toArray()) to inspect parsed nodes.CatchAll renderer in development to avoid crashes:
$renderer->append
How can I help you explore Laravel packages today?