html-to-gutenberg
Version:
Transform any valid HTML string into fully editable WP Gutenberg blocks in seconds rather than hours.
171 lines (133 loc) • 5.47 kB
Markdown
# HTML to Gutenberg Converter
[](https://github.com/DiogoAngelim/html-to-gutenberg/blob/main/LICENSE.MD)
Convert HTML into editable WordPress Gutenberg blocks and publish the generated package to Cloudflare R2 without writing the output to disk.
## What changed
- `html-to-gutenberg` now supports a `job` output mode that uploads generated files to R2 and returns a JSON manifest.
- `fetch-page-assets` can upload downloaded assets directly to R2 and return their metadata.
- Output bundles are zipped in memory and uploaded to R2 as `output.zip`.
- Secrets stay in `.env` and should never be committed.
## Installation
```bash
npm install html-to-gutenberg
```
## Environment
Copy `.env.example` to `.env` and keep the real values private.
```bash
cp .env.example .env
```
Required for R2-backed job output:
- `CLOUDFLARE_R2_ACCOUNT_ID`
- `CLOUDFLARE_R2_BUCKET`
- `CLOUDFLARE_R2_ACCESS_KEY_ID`
- `CLOUDFLARE_R2_SECRET_ACCESS_KEY`
- `CLOUDFLARE_R2_PUBLIC_BASE_URL`
Optional:
- `CLOUDFLARE_API_TOKEN`
- `SNAPAPI_KEY`
## Getting and rotating Cloudflare credentials
1. Open the Cloudflare dashboard.
2. Create or update your R2 access keys for the target bucket.
3. Store the new values in `.env`.
4. If you use a Cloudflare API token for verification or account workflows, create a new token in the API Tokens section and update `.env`.
5. Restart your app or redeploy after updating `.env`.
6. Revoke the old token or key after the new one is live.
To verify a Cloudflare API token without exposing it in code, use an environment variable:
```bash
curl "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```
## Usage
```js
import block from 'html-to-gutenberg';
const result = await block('<div>Hello world</div>', {
title: 'Marketing Hero',
slug: 'marketing-hero',
namespace: 'wp',
baseUrl: 'https://example.com',
outputMode: 'job',
uploadToR2: true,
jobId: 'conv_123'
});
console.log(result);
```
Example response:
```json
{
"jobId": "conv_123",
"status": "completed",
"output": {
"files": [
{
"id": "file_1",
"name": "block.js",
"type": "text/javascript",
"size": 18234,
"path": "/generated/conv_123/block.js",
"url": "https://storage.example.com/generated/conv_123/block.js",
"kind": "source"
},
{
"id": "file_2",
"name": "asset.png",
"type": "image/png",
"size": 48211,
"path": "/generated/conv_123/assets/asset.png",
"url": "https://storage.example.com/generated/conv_123/assets/asset.png",
"kind": "asset"
}
],
"bundle": {
"name": "output.zip",
"path": "/generated/conv_123/output.zip",
"url": "https://storage.example.com/generated/conv_123/output.zip",
"zipUrl": "https://storage.example.com/generated/conv_123/output.zip"
}
}
}
```
## Legacy mode
If you still need the previous local-string output for existing tooling or tests, use:
```js
const files = await block('<div>Hello world</div>', {
title: 'Legacy Block',
outputPath: process.cwd(),
writeFiles: false,
outputMode: 'legacy'
});
```
In `legacy` mode, the function returns the generated file contents instead of the R2 job manifest.
## Options
| Option | Description | Type | Default |
| --- | --- | --- | --- |
| `title` | Human-readable block title shown in the editor. | `string` | `My block` |
| `slug` | Filesystem-safe internal block name. Defaults to a slugified title. | `string` | slugified `title` |
| `baseUrl` | Base URL used to resolve relative asset paths in HTML and CSS. | `string \| null` | `null` |
| `namespace` | Gutenberg block namespace. | `string` | `wp` |
| `category` | Gutenberg block category. | `string` | `common` |
| `registerCategoryIfMissing` | Adds a custom editor category before block registration when needed. | `boolean` | `false` |
| `outputPath` | Absolute directory used for local legacy output. In `job` mode it is only a logical working base. | `string` | current directory |
| `writeFiles` | Writes local files in `legacy` mode. When `false`, returns generated files in memory. | `boolean` | `false` in the streamlined API |
| `generatePreviewImage` | Generates and uploads `preview.jpeg` using SnapAPI. | `boolean` | `false` |
| `jsFiles` | Remote JS dependencies to enqueue. | `string[]` | `[]` |
| `cssFiles` | Remote CSS dependencies to enqueue. | `string[]` | `[]` |
| `outputMode` | Advanced option. `job` uploads to R2 and returns JSON. `legacy` returns raw file contents. | `'job' \| 'legacy'` | `job`, unless local-output options imply `legacy` |
| `uploadToR2` | Advanced option to force or disable R2 uploads. | `boolean` | `true` in `job` mode |
| `jobId` | Advanced stable conversion identifier. | `string` | autogenerated |
Legacy aliases still work for backwards compatibility:
- `name` -> `title`
- `prefix` -> `namespace`
- `source` -> `baseUrl`
- `basePath` -> `outputPath`
- `shouldSaveFiles` -> `writeFiles`
- `generateIconPreview` -> `generatePreviewImage`
## Notes
- Generated output is zipped in memory before upload.
- R2 uploads use the values from `.env`.
- Do not hardcode real tokens or keys in source code, docs, or tests.
## Running tests
```bash
npm install
npm test
```
## License
[MIT](https://github.com/DiogoAngelim/html-to-gutenberg/blob/main/LICENSE.MD)