Page Blocks Builder 4Build a page. A tool. An experience.

Design with visual WordPress blocks, write your own HTML, CSS and JavaScript, or bring code from an AI tool. Put the canvas, source editors and live preview to work together.

Create landing pages, portfolios, calculators and interactive sections. Keep the source in WordPress and reuse the parts that work.

Free plugin. Every builder feature included. AI-provider usage is separate.

New in Page Blocks Builder 4

Visual Freedom. Code Control.

Build on the page, refine the source and move between both as the work changes. The new visual tools connect with the workflow you already know.

Page Blocks Builder 4 visual editing, code editing, auto and freeform placement, blank pages, conversion, canvas library, clipboard and media drag and drop.

This page is built with Page Blocks Builder. View the full-size overview.

Built With HTML, CSS and JavaScript

See What Your Code Can Become

A page can do more than display content. Try these working examples, then open the same source in the playground and make it your own.

Live exampleFilter the projects

A Portfolio With a Point of View

Create a visual identity, arrange your work and let visitors filter the projects they want to see.

Edit This Example
Live exampleMove the slider

A Calculator That Responds

Turn inputs into useful answers. Build quote tools, estimators and other small calculators with your own formulas.

Edit This Example
Live exampleCheck the tasks

An Interface People Can Use

Connect controls to live state. Make checklists, progress trackers and interactive content that responds to each action.

Edit This Example

These are browser examples with sample content, built from ordinary HTML, CSS and JavaScript. Accounts, payments and stored application data need the appropriate WordPress backend or external service.

Shape the Page

Use your own layouts, responsive CSS, type, color, imagery and motion for a landing page, product story or portfolio.

Make It Respond

Add filters, tabs, calculators, galleries and other interactions. Your JavaScript defines what happens next.

Build It Into WordPress

Keep a section with its page, reuse it from the library or place it through a shortcode, hook or theme region.

Try the Code. See the Result.

Choose an example, edit the HTML or CSS and watch the preview change. Update the JavaScript and select Run Code to try its behaviour.

Interactive Code Playground
HTML and CSS update as you type. Run JavaScript with Run Code.Browser-only example. Nothing is saved to WordPress.

Visual Blocks and Code, Together

Start in the mode that suits the section. Selecting a visual block opens Visual mode; selecting a code section brings its editors into view.

Design on the Canvas

Use native WordPress groups, headings, paragraphs, images and buttons. Edit supported blocks directly in the visual canvas.

  • Edit text and adjust type, color and spacing.
  • Use Auto layout or Freeform desktop placement.
  • Find nested content in Layers and use responsive styles.
  • Drop media from your desktop into the WordPress Media Library.

Work With Your Own Code

Keep HTML, CSS and JavaScript in separate editors beside the preview. Existing code sections retain their original workflow.

  • Bring your own code or a section from an AI tool.
  • Edit supported preview text without losing the source.
  • Check desktop, 992px, 768px, 480px and 360px widths.
  • Save code sections as Page Blocks in WordPress content.

Page Settings

Change the page title, slug, and available template from one dialog. These changes travel with the next save, so review the destination before saving.

JSON Import and Export

Export section data as JSON. Import can add sections after the existing ones or replace the page sections; export a backup before using replace.

Keep WordPress Blocks

Supported native blocks are editable on the canvas. Other blocks stay in the document and retain their Gutenberg editing workflow.

The Small Actions Add Up

Use the same editing actions across a page, and choose the canvas and source ownership that fit the work.

Visual ↔ Code

Convert supported sections when you need another editing mode. Native markup is retained; unsupported or ambiguous content stays code.

Copy, Cut and Paste

Reuse an element or move an entire section. Keyboard shortcuts and the editor clipboard support the same workflow.

A Blank Page

Choose the Blank canvas template when the page needs no theme header or footer. WordPress asset hooks remain available.

Auto or Freeform

Keep blocks in normal flow, or position and resize on desktop with snapping guides. At 768px and below, Freeform stacks in reading order.

Code Editing Tools

Small editor tools add up when you are adjusting several sections in a row.

CodeMirror Editors

Work with line numbers, bracket matching, folding, and separate HTML, CSS, and JavaScript panes. Editor undo is kept separate from document-level section actions.

HTML Snippets and Emmet

Insert common elements from the snippet buttons or wrap a selection. In the HTML editor, try section.hero>h1+p followed by Tab for a supported abbreviation.

Theme Class Suggestions

Use Ctrl/Cmd+Space to request class suggestions from the active theme context, helping you reuse classes your design already supplies.

Keyboard Navigation

Cmd/Ctrl+S saves, Cmd/Ctrl+K opens AI, and Cmd/Ctrl+B cycles preview widths. Alt+1, Alt+2, and Alt+3 focus the HTML, CSS, and JavaScript editors.

Shortcuts depend on focus. Code-editor undo and typing shortcuts should work on the text you are editing, while section commands apply to the document.

Keyboard shortcuts for saving, opening AI, moving sections, changing viewport, and focusing code editors

Copy It or Keep It Linked

A section can belong to one page or stay connected to a shared library block. Choose the ownership that fits the job.

A copy is independent. Changing one page’s section leaves the other copies alone.

Use copies for one-off designs. Use linked sections when the same change should reach every placement.

Example Section
Page 1
Page 2
Page 3

Try the color change, then switch ownership.

Reusable Block Library

Reuse is more useful when you can find a section, see where it is placed, and recover an earlier version.

Published Page Blocks library with search, sorting, live thumbnails, usage counts, and shortcode controls

Find the Right Block

Search by name, switch between published blocks, drafts, and trash, and sort by recent updates, title, or usage. Grid and list views suit different tasks.

Understand a Placement

Cards expose the slug, content-type badges, usage count, and copyable shortcode. Inspect the actual placements before changing a shared section.

Keep Useful Metadata

Give reusable sections clear titles, stable slugs, tags, and descriptions. A slug is easier to recognize in code than a site-specific numeric ID.

Recover Earlier Code

Library changes keep revision history with restore support. Revisions help recover code; they are not a replacement for a full backup of placement rules and site settings.

Publication Controls Rendering

Library shortcodes render published blocks. Keep unfinished shared blocks in draft while you prepare them, then publish only when their placements are ready. A linked block update can affect several live pages at once.

Section Placement and Conditions

One reusable section can serve a page, a shortcode placement, a WordPress hook, or a theme region. Select an example to see what each route needs.

Keep a Section With One Page

Use an inline Page Block when the section belongs to one page. Keep blockId at 0 and blockSlug empty so a library reference cannot override its source.

Examples show configuration and syntax. Replace sample slugs and content before using them.

<!-- wp:gt-page-block/page-block {"blockId":0,"blockSlug":"","name":"Contact Section","content":"<section>...</section>","css":"","js":"","phpExec":false} /-->

Target the Right Context

Conditions can narrow placement by post type, page type, and specific post ID. Page types include front page, singular content, archives, search, and 404 contexts.

Know Which Placements Honor Conditions

Positioned blocks and theme regions enforce their conditions. Gutenberg links use respectConditions; shortcode placements use conditions="true" when you want an opt-in check.

Use Rules Deliberately

Values within a condition group act as alternatives; separate nonempty groups must all match. An empty rule set is broad, so review it before activating a site-wide placement.

Keep Control of What Loads

Your published page uses the styles and scripts its sections need. Choose delivery deliberately and inspect the code before you save.

Choose the Delivery

Keep small CSS rules inline or give a section its own stylesheet. Use deferred CSS for later content while keeping hero and shared layout styles available early.

  • Choose inline or footer delivery for JavaScript.
  • Keep each section’s code with that section.
  • File generation falls back to inline CSS when storage is unavailable.

Inspect the Page Cost

The Performance panel reports authored code sizes and duplicate CSS, then flags common image and script loading issues.

  • Check image dimensions and loading hints.
  • Find blocking scripts and repeated styles.
  • Review unsaved work before publishing it.

These are diagnostics, not a PageSpeed score. Your authored code, media and integrations determine the browser’s work. Some markup checks require WordPress 6.2 or later.

AI and Agents Are Optional

Connect OpenAI, Anthropic, or Gemini when you want help drafting or editing code. Use authenticated REST access when your workflow belongs in a script or an agent.

  • Bring your own API key. Provider usage is billed separately.
  • Review generated HTML, CSS, and JavaScript before saving it.
  • The plugin exposes REST routes; it doesn’t bundle an MCP server.

AI requests can include section content and theme context. Only connect providers and editing tools you intend to use.

REST API pbb/v1
GET /wp-json/pbb/v1/blocks

POST /wp-json/pbb/v1/blocks
{
  "title": "Footer CTA",
  "status": "draft",
  "position": "",
  "content": "<section>...</section>",
  "css": "",
  "js": ""
}

Illustrative request. Authenticate through the documented WordPress route and use an account with the required permissions.

Gutenberg block
gt-page-block/page-block
Library shortcode
[page_block slug="footer-cta"]
Theme helper
gt_pb_region()
Developer Reference: REST API, WP-CLI and Permissions

REST API and WP-CLI

Use the same library objects from WordPress, scripts, or an authenticated agent. Keep permission checks and publication state part of the workflow.

MethodRoutePurpose
GET/wp-json/pbb/v1/blocksList and search library blocks, with status and pagination filters.
GET/wp-json/pbb/v1/blocks/{id}Read one library block and its saved fields.
POST/wp-json/pbb/v1/blocksCreate a block. Supply draft status and an empty position while preparing a new reusable section.
PUT / PATCH/wp-json/pbb/v1/blocks/{id}Update supported fields on an existing library block.
POST/wp-json/pbb/v1/blocks/{id}/duplicateCreate an independent duplicate.
DELETE/wp-json/pbb/v1/blocks/{id}Move a block to trash by default; permanent deletion is a separate operation.
GET/wp-json/pbb/v1/blocks/{id}/renderRequest rendered output subject to the plugin rendering and execution rules.

WP-CLI for Repeatable Tasks

Inspect the library or preview a legacy migration from the command line. The sample slug must refer to a real library item on your site.

wp gt-pb block list --status=publish --format=json
wp gt-pb block get footer-cta
wp gt-pb migrate-blocks --dry-run

Permissions and Safe Writes

  • REST reads require edit_posts; writes require manage_options.
  • Use WordPress application-password authentication or the authenticated session’s REST nonce.
  • Back up the current fields before a shared-block update.
  • Verify the stored result and affected placements after an authorized change.

REST library fields use php_exec and js_location. Gutenberg attributes use phpExec and jsLocation. They are different API surfaces.

Get Page Blocks Builder

FreeGPL-2.0-or-later

Visual editing, HTML/CSS/JavaScript tools, the reusable library and optional AI are all included.

The store provides a free update key. Activate it for normal automatic updates. AI-provider charges are separate.

From an Idea to WordPress

Start with one section and a clear job for it to do.

  1. 1

    Get the ZIP

    Complete the free checkout and download the plugin.

  2. 2

    Choose the Post Types

    Activate Page Blocks Builder and allow the post types you want to edit.

  3. 3

    Build and Save

    Insert a Page Block in Gutenberg or open the visual builder. Save your work and check the published result.

Requires WordPress 6.0+ and PHP 8.1+. Preview with your actual theme, integrations, and page template.

Browse the Source and Releases ↗

Before You Build

Editing choices, compatibility and the practical limits.

Is every builder feature free?

Yes. The visual canvas, code editors, library and other builder tools work without a license key. The free checkout provides an update key for automatic updates. Optional AI uses your own provider API key, with provider usage billed separately.

Do I need to write code?

You can build supported visual sections with native WordPress blocks. Use HTML, CSS and JavaScript when you want custom layouts, calculators or other interactions. You can also bring code from another tool or use the optional AI assistant.

Can I mix visual blocks and code?

Yes. Both can sit on the same page, and selecting a section activates its editing mode. Conversion is an explicit choice for supported content. Unsupported or ambiguous markup stays in code, and converted native block code requires 4.1.0 or later.

Can I keep my current theme?

The plugin works with classic and block themes. Keep the theme’s page shell or choose the Blank canvas template for a page without a header or footer. Named theme regions need matching gt_pb_region() calls in the theme.

Will my older sections keep working?

Existing code sections, linked library references and legacy Page Block names remain supported. Version 4 does not convert them automatically. You can keep the original code editing workflow and add visual sections when you need them.

Can I build a complete application with it?

You can build the page interface and its browser interactions using HTML, CSS and JavaScript, including tools like the examples above. Authentication, payments, database storage and server processing need the appropriate backend or integration. Optional PHP requires explicit site-level and per-block permission.

Your saved source remains in WordPress, but dynamic Page Blocks and library shortcodes need the plugin to render. Export or rebuild those sections before deactivating it. Ask a product question.

Your Next Page. Your Way.

Start with a visual block, a piece of code or one of your own ideas.

Visual freedom. Your code. WordPress underneath.

';status.textContent=runJs?'Preview updated':'HTML / CSS updated';root.querySelector('#pbw-preview-status').textContent='Live Preview';viewport();animate(frame,[{opacity:.55},{opacity:1}],{duration:260});};const codeTabs=[...root.querySelectorAll('[data-code-tab]')];const selectCode=(tab,focus=false)=>{code[pane]=editor.value;pane=tab.dataset.codeTab;editor.value=code[pane];editor.setAttribute('aria-label',pane==='js'?'JavaScript source':pane.toUpperCase()+' source');root.querySelector('#pbw-code-panel').setAttribute('aria-labelledby',tab.id);codeTabs.forEach(t=>{const on=t===tab;t.setAttribute('aria-selected',String(on));t.tabIndex=on?0:-1;});lines();if(focus)tab.focus();};codeTabs.forEach((t,i)=>{t.addEventListener('click',()=>selectCode(t));t.addEventListener('keydown',e=>{let n=null;if(e.key==='ArrowRight')n=(i+1)%codeTabs.length;if(e.key==='ArrowLeft')n=(i+codeTabs.length-1)%codeTabs.length;if(e.key==='Home')n=0;if(e.key==='End')n=codeTabs.length-1;if(n!==null){e.preventDefault();selectCode(codeTabs[n],true);}});});editor.addEventListener('input',()=>{code[pane]=editor.value;lines();clearTimeout(timer);if(pane==='js'){status.textContent='JavaScript changed. Select Run Code.';return;}status.textContent='Updating preview…';timer=setTimeout(()=>render(false),350);});editor.addEventListener('scroll',()=>{gutter.scrollTop=editor.scrollTop;});editor.addEventListener('keydown',e=>{if((e.metaKey||e.ctrlKey)&&e.key==='Enter'){e.preventDefault();clearTimeout(timer);render(true);}});root.querySelector('.pbw-run').addEventListener('click',()=>{clearTimeout(timer);render(true);});const reset=()=>{clearTimeout(timer);code={...samples[selectedExample]};runningJs=code.js;editor.value=code[pane];lines();render(true);};example.addEventListener('change',()=>{selectedExample=Number(example.value);reset();});root.querySelector('.pbw-reset').addEventListener('click',reset);root.querySelector('.pbw-copy').addEventListener('click',async()=>{try{await navigator.clipboard.writeText(editor.value);status.textContent='Code copied';}catch{editor.focus();editor.select();status.textContent='Code selected. Use your copy shortcut.';}});root.querySelectorAll('[data-preview-width]').forEach(button=>button.addEventListener('click',()=>{previewWidth=button.dataset.previewWidth;root.querySelectorAll('[data-preview-width]').forEach(b=>b.setAttribute('aria-pressed',String(b===button)));viewport();animate(stage,[{opacity:.6},{opacity:1}]);}));root.querySelector('.pbw-preview-theme').addEventListener('click',e=>{previewDark=!previewDark;e.currentTarget.setAttribute('aria-pressed',String(previewDark));render(false);});if('ResizeObserver'in window)new ResizeObserver(viewport).observe(stage);frame.addEventListener('load',viewport);lines();render(true);const galleryTabs=[...root.querySelectorAll('[data-gallery]')];const selectGallery=(tab,focus=false)=>{galleryTabs.forEach(t=>{const on=t===tab;t.setAttribute('aria-selected',String(on));t.tabIndex=on?0:-1;root.querySelector('#'+t.getAttribute('aria-controls')).hidden=!on;});if(focus)tab.focus();animate(root.querySelector('#'+tab.getAttribute('aria-controls')),[{opacity:.4,transform:'translateY(10px)'},{opacity:1,transform:'translateY(0)'}]);};galleryTabs.forEach((t,i)=>{t.addEventListener('click',()=>selectGallery(t));t.addEventListener('keydown',e=>{let n=null;if(e.key==='ArrowRight')n=(i+1)%galleryTabs.length;if(e.key==='ArrowLeft')n=(i+galleryTabs.length-1)%galleryTabs.length;if(e.key==='Home')n=0;if(e.key==='End')n=galleryTabs.length-1;if(n!==null){e.preventDefault();selectGallery(galleryTabs[n],true);}});});let mode='copy',alternate=false;const pages=[...root.querySelectorAll('.pbw-demo-page')],reuseRoot=root.querySelector('.pbw-reuse-demo');const resetReuse=()=>{alternate=false;pages.forEach(p=>p.classList.remove('is-changed'));root.querySelector('.pbw-reuse-result').textContent='Try the color change, then switch ownership.';};root.querySelectorAll('[data-reuse]').forEach(button=>button.addEventListener('click',()=>{mode=button.dataset.reuse;reuseRoot.dataset.mode=mode;root.querySelectorAll('[data-reuse]').forEach(b=>b.setAttribute('aria-pressed',String(b===button)));root.querySelector('.pbw-reuse-explanation').textContent=mode==='copy'?"A copy is independent. Changing one page's section leaves the other copies alone.":'A linked section uses one library source. Update it once and each linked placement receives the change.';resetReuse();}));root.querySelector('.pbw-change-source').addEventListener('click',()=>{alternate=!alternate;pages.forEach((page,i)=>{const affected=mode==='linked'||i===0;if(affected){page.classList.toggle('is-changed',alternate);animate(page,[{transform:'translateY(-8px)',opacity:.65},{transform:'translateY(0)',opacity:1}]);}});root.querySelector('.pbw-reuse-result').textContent=mode==='linked'?'All 3 linked placements changed together.':'Only the independent section on Page 1 changed.';});if('IntersectionObserver'in window){const reveal=new IntersectionObserver(entries=>{entries.forEach(entry=>{if(entry.isIntersecting){animate(entry.target,[{opacity:.35,transform:'translateY(22px)'},{opacity:1,transform:'translateY(0)'}],{duration:600});reveal.unobserve(entry.target);}});},{threshold:.15});root.querySelectorAll('[data-reveal]').forEach(el=>reveal.observe(el));}const header=document.querySelector('#header'),admin=document.getElementById('wpadminbar');const measure=()=>root.style.setProperty('--nav-offset',Math.round((header?header.getBoundingClientRect().height:60)+(admin?admin.getBoundingClientRect().height:0))+'px');measure();if(header&&'ResizeObserver'in window)new ResizeObserver(measure).observe(header);window.addEventListener('resize',measure,{passive:true});const bar=root.querySelector('.pbw-buybar'),watched=[hero,root.querySelector('#download'),root.querySelector('.pbw-close')],visible=new Set(watched);const syncBar=()=>{bar.hidden=visible.size>0||innerWidth>1023;};if('IntersectionObserver'in window){const ob=new IntersectionObserver(entries=>{entries.forEach(e=>e.isIntersecting?visible.add(e.target):visible.delete(e.target));root.dataset.closeVisible=String(visible.has(watched[2]));syncBar();});watched.forEach(el=>ob.observe(el));window.addEventListener('resize',syncBar,{passive:true});}root.querySelectorAll('.pbw-hero-copy h1,.pbw-hero-copy .pbw-lead,.pbw-hero-copy .pbw-intro,.pbw-hero-copy .pbw-actions').forEach((el,i)=>animate(el,[{opacity:.2,transform:'translateY(16px)'},{opacity:1,transform:'translateY(0)'}],{duration:650,delay:i*70}));})();(()=>{const root=document.querySelector('.pbw-page');if(!root)return;root.querySelectorAll('[data-pbc-edit]').forEach(link=>link.addEventListener('click',event=>{event.preventDefault();const select=root.querySelector('#pbw-example');select.value=link.dataset.pbcEdit;select.dispatchEvent(new Event('change',{bubbles:true}));const htmlTab=root.querySelector('[data-code-tab="html"]');htmlTab.click();root.querySelector('#playground').scrollIntoView({behavior:matchMedia('(prefers-reduced-motion: reduce)').matches?'auto':'smooth',block:'start'});root.querySelector('#pbw-source').focus({preventScroll:true});}));})();;(()=>{const root=document.querySelector('.pbw-page');if(!root||root.dataset.expandedReady)return;root.dataset.expandedReady='true';const examples=[{"key":"inline","label":"Page Section","title":"Keep a Section With One Page","text":"Use an inline Page Block when the section belongs to one page. Keep blockId at 0 and blockSlug empty so a library reference cannot override its source.","code":""},{"key":"shortcode","label":"Shortcode","title":"Place a Published Library Block","text":"Use the registered page_block shortcode in a shortcode-capable location. Refer to the published library block by its real ID or slug. Opt into conditions when you want them applied to this placement.","code":"[page_block slug=\"footer-cta\"]\n\n[page_block slug=\"footer-cta\" conditions=\"true\"]"},{"key":"hook","label":"WordPress Hook","title":"Attach a Block to a Hook","text":"Set a library block position to an available WordPress hook, choose its priority, and narrow its conditions. The hook must actually fire in your theme or template.","code":"position: wp_footer\npriority: 10\nstatus: publish\n\nconditions:\n{ \"post_types\": [\"page\"] }"},{"key":"region","label":"Theme Region","title":"Give a Theme Region Editable Content","text":"Assign the block to a matching region and have the theme call the helper. A region assignment alone does not add a header, footer, or sidebar to an arbitrary template.","code":"position: region:footer\n\n false ) );\n?>"}],tabs=[...root.querySelectorAll('[data-placement]')],panel=root.querySelector('#pbx-placement-panel');const select=(button,focus=false)=>{const i=Number(button.dataset.placement),item=examples[i];root.querySelector('#pbx-placement-title').textContent=item.title;root.querySelector('#pbx-placement-text').textContent=item.text;root.querySelector('#pbx-placement-code').textContent=item.code;panel.setAttribute('aria-labelledby',button.id);tabs.forEach(t=>{const on=t===button;t.setAttribute('aria-selected',String(on));t.tabIndex=on?0:-1;});if(focus)button.focus();if(root.dataset.motion==='running'&&!matchMedia('(prefers-reduced-motion: reduce)').matches)panel.animate([{opacity:.55,transform:'translateY(9px)'},{opacity:1,transform:'translateY(0)'}],{duration:280,easing:'ease-out'});};tabs.forEach((button,i)=>{button.addEventListener('click',()=>select(button));button.addEventListener('keydown',event=>{let next=null;if(event.key==='ArrowRight')next=(i+1)%tabs.length;if(event.key==='ArrowLeft')next=(i+tabs.length-1)%tabs.length;if(event.key==='Home')next=0;if(event.key==='End')next=tabs.length-1;if(next!==null){event.preventDefault();select(tabs[next],true);}});});})();