Getting Started
v1.0.0 STABLE RELEASE
🎉 WP Block to HTML v1.0.0 is now available! This stable release includes production-ready client-side hydration, comprehensive framework support, and performance optimizations achieving 947 blocks/ms processing speed.
IMPORTANT: Accessing Block Content
You cannot directly access raw block content from WordPress.
To use WP Block to HTML with raw block data, you'll need to install a plugin to expose this content. We're developing an official plugin with proper security measures to safely expose this data.
In the meantime, you can use a plugin like Post Raw Content to access block data.
Note: You can still use this package without a plugin by working with the rendered HTML content that WordPress provides by default. The package will handle rendered HTML content automatically, as shown in the "Option 2" example below.
Stay tuned for our official plugin release!
This guide will help you quickly integrate WP Block to HTML v1.0.0 into your project and convert WordPress content into clean, framework-compatible HTML with optional client-side hydration.
Installation
Install the stable v1.0.0 release using your preferred package manager:
npm install wp-block-to-html
yarn add wp-block-to-html
pnpm add wp-block-to-html
Quick Start
Step 1: Import the library
import { convertBlocks } from 'wp-block-to-html';
// NEW in v1.0.0: Import hydration module for client-side hydration
import { HydrationManager } from 'wp-block-to-html/hydration';
Step 2: Prepare your WordPress block data
// WordPress Gutenberg block data
const blockData = {
blocks: [
{
blockName: 'core/paragraph',
attrs: { align: 'center' },
innerContent: ['<p>Hello WordPress!</p>']
},
{
blockName: 'core/heading',
attrs: { level: 2 },
innerContent: ['<h2>Welcome to Headless WordPress</h2>']
}
]
};
Step 3: Convert blocks to HTML
// Convert to HTML with default settings
const html = convertBlocks(blockData);
console.log(html);
// Output:
// <p class="wp-block-paragraph has-text-align-center">Hello WordPress!</p>
// <h2 class="wp-block-heading">Welcome to Headless WordPress</h2>
Step 4: Use the converted HTML in your application
// React example
function MyComponent() {
return <div dangerouslySetInnerHTML={{ __html: html }} />;
}
// Vanilla JavaScript
document.getElementById('content').innerHTML = html;
Step 5: Add Client-Side Hydration (NEW in v1.0.0)
// Initialize hydration manager with progressive loading
const hydrationManager = new HydrationManager({
strategy: 'viewport', // viewport, interaction, idle, immediate
rootSelector: '#content',
throttle: 100
});
// Hydrate specific blocks when they become visible
await hydrationManager.hydrateBlock('core/gallery');
// Or hydrate all interactive blocks progressively
await hydrationManager.hydrateAll();
Handling WordPress REST API Content
The WordPress REST API doesn't expose raw block data by default. You'll need a plugin to access this data:
Option 1: Raw Block Data (Preferred)
// IMPORTANT: You need to install a plugin like Post Raw Content to expose block data
// https://github.com/w1z2g3/wordpress-plugins/blob/master/post-raw-content.php
//
// Once installed, you can fetch the block data:
async function fetchPost() {
const response = await fetch('https://example.com/wp-json/wp/v2/posts/1?_fields=id,title,content,blocks');
const post = await response.json();
if (post.blocks) {
const html = convertBlocks(post.blocks, {
cssFramework: 'tailwind',
contentHandling: 'raw',
hydration: {
strategy: 'progressive',
priorityBlocks: ['core/button', 'core/gallery']
}
});
document.getElementById('content').innerHTML = html;
// NEW in v1.0.0: Set up hydration for interactive blocks
const hydrationManager = new HydrationManager({
strategy: 'viewport',
rootSelector: '#content'
});
await hydrationManager.hydrateAll();
}
}
Option 2: Rendered HTML Content (Always Available)
If block data isn't available, you can use the rendered HTML:
async function fetchPost() {
const response = await fetch('https://example.com/wp-json/wp/v2/posts/1?_fields=id,title,content');
const post = await response.json();
if (post.content && post.content.rendered) {
// Option A: Use rendered content directly
document.getElementById('content').innerHTML = post.content.rendered;
// Option B: Pass rendered content through the library for processing
const html = convertBlocks({
rendered: post.content.rendered
}, {
contentHandling: 'rendered',
cssFramework: 'tailwind',
hydration: { strategy: 'idle' } // NEW in v1.0.0
});
document.getElementById('content').innerHTML = html;
}
}
Complete Example with Error Handling
Here's a complete example that handles both block data and rendered content with proper fallbacks and hydration:
import { convertBlocks } from 'wp-block-to-html';
import { HydrationManager } from 'wp-block-to-html/hydration';
async function displayWordPressPost(postId) {
try {
// Fetch post data
const response = await fetch(`https://example.com/wp-json/wp/v2/posts/${postId}?_fields=id,title,content,blocks`);
if (!response.ok) {
throw new Error(`Failed to fetch post: ${response.status} ${response.statusText}`);
}
const post = await response.json();
let content = '';
let useHydration = false;
// Process content based on what's available
if (post.content) {
console.log('Processing raw block data...');
content = convertBlocks(post.content, {
cssFramework: 'tailwind',
contentHandling: 'raw',
hydration: {
strategy: 'progressive',
priorityBlocks: ['core/button', 'core/gallery', 'core/video']
}
});
useHydration = true;
} else if (post.content && post.content.rendered) {
console.log('Using rendered content...');
content = post.content.rendered;
} else {
console.warn('No content found for this post');
content = '<div class="error">No content available</div>';
}
// Display the content
document.getElementById('post-title').textContent = post.title.rendered;
document.getElementById('post-content').innerHTML = content;
// NEW in v1.0.0: Set up client-side hydration if using raw blocks
if (useHydration) {
const hydrationManager = new HydrationManager({
strategy: 'viewport',
rootSelector: '#post-content',
throttle: 100
});
// Hydrate interactive blocks progressively
await hydrationManager.hydrateAll();
console.log('✅ Client-side hydration complete');
}
} catch (error) {
console.error('Error displaying post:', error);
document.getElementById('post-content').innerHTML =
`<div class="error">Error loading content: ${error.message}</div>`;
}
}
// Usage
displayWordPressPost(123);
CSS Framework Integration
You can output HTML with classes from popular CSS frameworks:
// With Tailwind CSS
const tailwindHtml = convertBlocks(blockData, {
cssFramework: 'tailwind',
hydration: { strategy: 'viewport' } // NEW in v1.0.0
});
console.log(tailwindHtml);
// Output:
// <p class="text-center">Hello WordPress!</p>
// <h2 class="text-2xl font-bold">Welcome to Headless WordPress</h2>
// With Bootstrap
const bootstrapHtml = convertBlocks(blockData, {
cssFramework: 'bootstrap'
});
console.log(bootstrapHtml);
// Output:
// <p class="text-center">Hello WordPress!</p>
// <h2 class="h2">Welcome to Headless WordPress</h2>
Custom Configuration
For more control, you can provide a complete configuration object:
const html = convertBlocks(blockData, {
// Output format (default: 'html')
outputFormat: 'html', // 'html' | 'react' | 'vue' | 'angular' | 'svelte'
// CSS framework (default: 'none')
cssFramework: 'tailwind', // 'none' | 'tailwind' | 'bootstrap' | 'custom'
// Content handling (default: 'raw')
contentHandling: 'raw', // 'raw' | 'rendered' | 'hybrid'
// Server-side rendering optimizations
ssrOptions: {
enabled: true,
optimizationLevel: 'balanced', // 'minimal' | 'balanced' | 'maximum'
lazyLoadMedia: true
}
});
Troubleshooting Common Issues
Issue: Blocks Not Converting Correctly
If your blocks aren't converting as expected:
// Enable debugging to see detailed information
const html = convertBlocks(blockData, {
debug: true
});
Issue: WordPress API Not Returning Block Data
If you're not getting block data from the WordPress API:
Make sure you've installed a plugin to expose raw block content. We recommend:
- Post Raw Content (temporary solution)
- Our official plugin (coming soon)
Check that the plugin is properly installed and activated.
Verify that your API request includes the necessary fields:
javascript// Make sure to request the blocks field const response = await fetch('https://example.com/wp-json/wp/v2/posts/1?_fields=id,title,content,blocks');
Issue: Poor Performance with Large Content
If you experience performance issues with large content sets:
// Use incremental rendering for large content
const html = convertBlocks(largeBlockData, {
incrementalOptions: {
enabled: true,
initialRenderCount: 10,
batchSize: 5
}
});
Browser Compatibility
WP Block to HTML works in all modern browsers (Chrome, Firefox, Safari, Edge) and Node.js environments. For IE11 support, you'll need appropriate polyfills.
Next Steps
Now that you understand the basics, explore these topics:
- Content Handling Modes - Choose between raw, rendered, or hybrid content processing
- CSS Framework Integration - Customize output for your preferred CSS framework
- SSR Optimizations - Optimize for server-side rendering performance
- Bundle Size Optimization - Reduce bundle size with modular imports
- Lazy Loading Media - Improve performance with lazy-loaded images and videos