If you're using Payload CMS with Next.js and Tailwind CSS, you've probably encountered a frustrating issue: your rich text editor renders lists perfectly in the admin interface, but when enableProse={false} on the frontend, the bullet points or numbers simply vanish. The lists render as plain text lines, making your content difficult to read.
I recently built a system with multiple content blocks that needed fine-grained control over list styling. Rather than relying on Tailwind's prose classes globally, I implemented a preventative pattern that ensures lists display correctly regardless of your prose settings. This guide walks you through that exact implementation.
Understanding the Problem
When you set enableProse={true} in your RichTextRenderer component, Tailwind's prose classes handle all list styling automatically—bullets, numbering, padding, margins. Everything works.
But when you set enableProse={false} (which is common for About sections, FAQ answers, and any block-level content where you want precise style control), you lose that automatic styling. The <ul> and <ol> elements render as bare HTML with no visual indicators that they're lists.
This happens because HTML resets default list styles by default, and without Tailwind's prose classes to re-enable them, the browser treats lists like regular <div> elements.
The Correct Implementation Pattern
The key is to apply explicit list styling utilities when prose is disabled. Here's the correct approach:
The critical part is the conditional className logic. When enableProse={false}, the component now applies three essential utilities:
[&_ul]:list-disc — Shows bullet points for unordered lists
[&_ol]:list-decimal — Shows numbers for ordered lists
[&_ul]:pl-10 [&_ol]:pl-10 — Adds 40px padding so bullets/numbers don't overlap the text
When enableProse={true}, those utilities aren't needed because the prose classes already handle list styling. We only apply base padding (pl-5) in that case.
These CSS rules work alongside the Tailwind utilities. They ensure that even if Tailwind's utilities don't generate or apply correctly, the browser still renders lists properly. The !important flags guarantee these styles override any conflicting resets.
Understanding the Approach
Why both Tailwind utilities and CSS rules? It provides defense-in-depth:
Tailwind utilities ([&_ul]:list-disc) are your primary layer. They apply when Tailwind processes your build and are the modern, maintainable approach.
CSS rules in globals.css are your fallback. They catch edge cases where Tailwind utilities don't generate or apply—particularly useful when the component is part of a custom field in Payload where styling contexts might differ.
The combination of both ensures lists display correctly in every scenario.
Verification and Troubleshooting
Once you've made these changes, verify the implementation:
1. Check Your Component Usage
Anywhere you use RichTextRenderer with enableProse={false}, verify you're passing it rich text data that contains lists.
This usage is correct. The component receives rich text data and renders lists without prose styling.
2. Clear Your Next.js Cache
This is the critical preventative step many developers miss. After making these changes, clear the Next.js build cache:
bash
rm -rf .next
Then restart your development server. This ensures Tailwind reprocesses all your arbitrary selectors ([&_ul]:list-disc, etc.) and generates the correct CSS. Without this step, the utilities might not generate even though the code is correct.
3. Visual Inspection
Navigate to a page using your RichTextRenderer with enableProse={false}. Look for:
Bullet points visible in unordered lists
Numbers visible in ordered lists
Proper indentation (bullets/numbers not touching the text)
Consistent spacing between list items
If all four conditions are met, your implementation is working correctly.
4. Type Check
Run TypeScript verification to ensure no type errors:
bash
npx tsc --noEmit
Key Takeaways
The pattern for correct list styling in RichTextRenderer is straightforward:
Use conditional Tailwind utilities that apply only when enableProse={false}
Include both list-style and padding utilities — bullets/numbers require both to display properly
Add supporting CSS rules in your global styles as a fallback
Clear your build cache after making changes so utilities generate correctly
This preventative approach means you'll never encounter the frustrating "lists render as plain text" issue. Your lists will display correctly from day one, whether prose is enabled or disabled.
Common Variations
If you need to support different list styles for different blocks, extend the pattern:
typescript
// For blocks that need tighter spacing'[&_li]:mb-1': !enableProse,
// For blocks that need custom indentation'[&_ul]:pl-12 [&_ol]:pl-12': !enableProse,
// For blocks with nested lists'[&_ul_ul]:list-circle [&_ul_ul_ul]:list-square': !enableProse,
The underlying principle remains the same: when prose is disabled, you must explicitly tell Tailwind and CSS which list styles to apply.
By following this preventative pattern, you ensure lists display correctly in your rich text content regardless of your prose settings. The combination of explicit Tailwind utilities, supporting CSS rules, and cache clearing creates a robust implementation that works reliably across all your content blocks.
Let me know in the comments if you have questions about implementing this in your own project, and subscribe for more practical development guides.