<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andrea Tasselli</title>
    <description>The latest articles on DEV Community by Andrea Tasselli (@andreata).</description>
    <link>https://dev.to/andreata</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3807765%2F0ebeb452-ac05-417f-8584-71936f27b36b.png</url>
      <title>DEV Community: Andrea Tasselli</title>
      <link>https://dev.to/andreata</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andreata"/>
    <language>en</language>
    <item>
      <title>The WordPress Plugin Stack I Install on Every Single Site (And Why)</title>
      <dc:creator>Andrea Tasselli</dc:creator>
      <pubDate>Thu, 09 Apr 2026 14:08:25 +0000</pubDate>
      <link>https://dev.to/andreata/the-wordpress-plugin-stack-i-install-on-every-single-site-and-why-591j</link>
      <guid>https://dev.to/andreata/the-wordpress-plugin-stack-i-install-on-every-single-site-and-why-591j</guid>
      <description>&lt;p&gt;After 200+ WordPress sites, my plugin stack has converged to the same 9 plugins. Every time.&lt;/p&gt;

&lt;p&gt;Not because I'm lazy. Because I've tried the alternatives, broken things in production, dealt with plugin conflicts at 2am, and slowly eliminated everything that wasn't essential.&lt;/p&gt;

&lt;p&gt;This is the stack I install on every site I build — including the ones generated by &lt;a href="https://megify.ai" rel="noopener noreferrer"&gt;Megify&lt;/a&gt;, the AI platform I'm building. Every plugin here earns its place. If it doesn't solve a real problem, it's not on the list.&lt;/p&gt;




&lt;h2&gt;
  
  
  The rules
&lt;/h2&gt;

&lt;p&gt;Before the list, the rules I follow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fewer plugins = fewer problems.&lt;/strong&gt; Every plugin is a potential security hole, a performance hit, and a compatibility risk. If I can do it without a plugin, I do.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No plugin does two jobs.&lt;/strong&gt; SEO plugin does SEO. Cache plugin does caching. I don't want an "all-in-one" plugin that does 17 things badly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free tier must be usable.&lt;/strong&gt; If the free version is crippled to the point of uselessness, the plugin is a sales funnel, not a tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active maintenance.&lt;/strong&gt; If the last update was 6 months ago, it's dead. WordPress core updates break unmaintained plugins.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Rank Math (SEO)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Meta titles, descriptions, schema markup, sitemap, redirects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why not Yoast:&lt;/strong&gt; I used Yoast for years. Rank Math does the same things with a cleaner UI, better schema markup options, and the free version includes features that Yoast locks behind premium (redirects, multiple keyword tracking, schema types).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The setup I use:&lt;/strong&gt; Enable only the modules you need. I typically turn on: SEO Analysis, Sitemap, Schema, Redirections, and 404 Monitor. Everything else stays off. Rank Math with all 15 modules enabled is bloated. With 5, it's lean.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One thing people miss:&lt;/strong&gt; The "Instant Indexing" module. It pings Google via the Indexing API when you publish or update content. Pages get indexed in minutes instead of days. You need a Google API key, but it's free and takes 10 minutes to set up.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. WP Rocket (Caching + Performance)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Page caching, browser caching, GZIP compression, CSS/JS minification, lazy loading, database optimization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it's worth paying for:&lt;/strong&gt; This is the one paid plugin on my list (€59/year for a single site). I've tried every free caching plugin — W3 Total Cache, WP Super Cache, LiteSpeed Cache. They all work. But WP Rocket works out of the box with zero configuration. Install, activate, done. No 47 settings tabs, no breaking your site because you enabled the wrong option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The setting most people miss:&lt;/strong&gt; "Preload Cache" — it crawls your site and generates cached versions of every page in advance. First-time visitors get a cached page instead of waiting for PHP to render. Combined with "Preload Links" (prefetches pages on hover), navigation feels instant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you can't afford it:&lt;/strong&gt; LiteSpeed Cache if your host supports LiteSpeed (many do now). Otherwise WP Super Cache — ugly interface, reliable caching.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Wordfence (Security)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Firewall, malware scanner, login security, brute force protection, real-time threat intelligence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters:&lt;/strong&gt; WordPress is 40% of the web. That makes it target #1 for automated attacks. Without a security plugin, you're relying on hope. Wordfence's firewall blocks most attacks before they reach your site.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The free version is enough.&lt;/strong&gt; Premium adds real-time firewall rules (free users get them 30 days later) and real-time malware signatures. For most sites, the free version with 30-day delayed rules is perfectly adequate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The settings I change:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable 2FA for all admin accounts. Non-negotiable.&lt;/li&gt;
&lt;li&gt;Set "Lock out after how many login failures" to 5.&lt;/li&gt;
&lt;li&gt;Enable "Rate Limit" for crawlers and humans.&lt;/li&gt;
&lt;li&gt;Disable XML-RPC in the firewall settings (it's an attack vector nobody needs in 2026).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. UpdraftPlus (Backups)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Automated backups to remote storage (Google Drive, Dropbox, S3).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it's critical:&lt;/strong&gt; Your hosting provider probably does backups. But can you access them easily? Can you restore a specific page from 3 weeks ago? Can you download a full backup to your local machine? With UpdraftPlus, yes to all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My setup:&lt;/strong&gt; Full backup every week to Google Drive. Database-only backup daily. Keep the last 4 weekly backups and 7 daily database backups. This means I can restore to any day in the last week, or any week in the last month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The mistake I see constantly:&lt;/strong&gt; People install a backup plugin but never test a restore. A backup you can't restore is not a backup. Every 3 months, download a backup, spin up a local WordPress, and restore it. Make sure it works.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. WPForms Lite (Forms)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Contact forms, with drag-and-drop builder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this and not Contact Form 7:&lt;/strong&gt; CF7 works. I used it for a decade. But every time I set up a form with CF7, I spend 20 minutes fighting with the markup and the mail configuration. WPForms Lite lets me build a contact form in 2 minutes with a visual builder. For a contact form — which is all most sites need — the speed difference matters when you're building sites at scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The limitation of the free version:&lt;/strong&gt; No payment forms, no multi-step forms, no conditional logic. If you need any of these, you need Pro. But for a standard "Name, Email, Message, Send" form, Lite is all you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alternative:&lt;/strong&gt; Fluent Forms free version if you need more fields without paying.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Imagify (Image Optimization)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Compresses images on upload. Supports WebP conversion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters:&lt;/strong&gt; Images are typically 60-80% of a page's weight. An unoptimized 3MB hero image kills your Core Web Vitals, your Lighthouse score, and your user experience on mobile. Imagify compresses images on upload with no visible quality loss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The setting that saves bandwidth:&lt;/strong&gt; Enable WebP conversion. WebP images are 25-35% smaller than JPEG at equivalent quality. All modern browsers support WebP. Imagify creates the WebP version and serves it automatically — no code changes needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free tier:&lt;/strong&gt; 20MB/month of image optimization. For a small site with occasional uploads, it's enough. For an ecommerce with hundreds of product images, you'll need the paid plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alternative:&lt;/strong&gt; ShortPixel does the same thing with a similar free tier.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Redirection (URL Management)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Manages 301 redirects and tracks 404 errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why you need it:&lt;/strong&gt; Every time you change a URL, delete a page, or restructure your site, old URLs break. That's lost SEO value and a bad user experience. Redirection catches 404s and lets you redirect them to the right page with two clicks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The thing most people don't know:&lt;/strong&gt; Redirection can automatically create a redirect when you change a post's permalink. Enable "Monitor permalink changes" in settings. Now you never have to worry about changing a URL — the redirect is created automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is free.&lt;/strong&gt; Fully featured, no premium version, no upsells. One of the best free plugins in the WordPress ecosystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. WooCommerce (When Needed)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Turns WordPress into a full ecommerce platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When I install it:&lt;/strong&gt; Only when the site needs to sell something — physical products, digital downloads, services, bookings. I don't install it "just in case." WooCommerce adds significant database tables and admin complexity. If you don't need it, don't install it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The configuration that matters most:&lt;/strong&gt; Stripe as primary payment gateway (lowest fees for European cards: 1.4% + €0.25), PayPal as secondary (some customers don't want to enter card details). Shipping zones configured correctly for the target market. Tax settings using a tax plugin or manual rates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The plugin I add to WooCommerce:&lt;/strong&gt; Just one — a shipping plugin specific to the client's country (for Italy, I typically use one that integrates with BRT or GLS rates). Everything else WooCommerce does natively.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Elementor (Page Builder)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Visual drag-and-drop page editing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; Because clients need to edit their pages. And "edit in Gutenberg" still means "learn a block editor that changes every WordPress update." Elementor's interface is stable, visual, and understood by millions of users. When I hand off a site, the client can edit text, swap images, and rearrange sections without calling me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free vs Pro:&lt;/strong&gt; The free version handles most landing pages and basic sites. Pro (€59/year) adds theme builder, popup builder, WooCommerce widgets, and custom fonts. For a business site, Pro is usually worth it. For a simple site, free is fine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The performance concern:&lt;/strong&gt; Yes, Elementor adds weight — extra CSS, JS, and DOM elements. But with WP Rocket's minification and a good hosting setup, the impact is manageable. A well-built Elementor site scores 85-90 on Lighthouse. Not perfect, but good enough for a business site where editability matters more than a 100 Lighthouse score.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I don't install
&lt;/h2&gt;

&lt;p&gt;This list is as important as what I install:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No "all-in-one" plugins.&lt;/strong&gt; Jetpack does 30 things. I need 0 of them badly enough to install a plugin that big. Same for plugins that combine security + performance + SEO. Do one thing well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No social sharing plugins.&lt;/strong&gt; They add bloat for minimal value. If someone wants to share, they'll copy the URL. The share buttons with counters showing "0 shares" do more harm than good.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No analytics plugins.&lt;/strong&gt; Google Analytics is a script tag, not a plugin. Adding a plugin to insert one script tag is unnecessary. I add the GA4 tag via Google Tag Manager, which is also a single script tag. If the client needs a dashboard in WordPress, I use Site Kit by Google — but only if they ask.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No maintenance mode plugins.&lt;/strong&gt; A &lt;code&gt;maintenance.html&lt;/code&gt; file and an &lt;code&gt;.htaccess&lt;/code&gt; rule does the same thing without a plugin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No database optimization plugins.&lt;/strong&gt; WP Rocket includes database cleanup. Adding another plugin for the same job is redundant.&lt;/p&gt;




&lt;h2&gt;
  
  
  The stack in production
&lt;/h2&gt;

&lt;p&gt;This is the exact stack running on the sites generated by &lt;a href="https://megify.ai" rel="noopener noreferrer"&gt;Megify&lt;/a&gt;. When the AI creates a WordPress site, these plugins are pre-installed and pre-configured with the settings described above. The user gets a site that's fast, secure, SEO-ready, and backed up — without installing or configuring anything.&lt;/p&gt;

&lt;p&gt;It's not the most exciting part of the platform. But it's the part that keeps sites running reliably at 3am when nobody's watching.&lt;/p&gt;




&lt;p&gt;What's your WordPress plugin stack? I'm always curious about what other developers have converged on after years of trial and error.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Got Tired of Clicking "Accept" 100 Times a Day in Claude Code. So I Built a Menu Bar App</title>
      <dc:creator>Andrea Tasselli</dc:creator>
      <pubDate>Wed, 18 Mar 2026 13:41:25 +0000</pubDate>
      <link>https://dev.to/andreata/i-got-tired-of-clicking-accept-100-times-a-day-in-claude-code-so-i-built-a-menu-bar-app-25oj</link>
      <guid>https://dev.to/andreata/i-got-tired-of-clicking-accept-100-times-a-day-in-claude-code-so-i-built-a-menu-bar-app-25oj</guid>
      <description>&lt;p&gt;If you use Claude Code in VS Code, you know the pain.&lt;/p&gt;

&lt;p&gt;Claude wants to edit a file. "Allow?" Click. Claude wants to run a command. "Allow?" Click. Claude wants to read a directory. "Allow?" Click.&lt;/p&gt;

&lt;p&gt;On a productive day, I click "Accept" 50-100 times. It breaks flow, interrupts thinking, and adds up to minutes of pure friction.&lt;/p&gt;

&lt;p&gt;So I built a macOS menu bar app that does it for me.&lt;/p&gt;




&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;Claude Auto Accept sits in your macOS menu bar and monitors Claude Code for permission prompts. When one appears, it either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Auto-accepts it&lt;/strong&gt; (fully automatic mode) — Claude runs uninterrupted. At the end, you get a notification with the total count of accepted prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accepts via keyboard shortcut&lt;/strong&gt; (⌘⇧⌥0 to Accept, ⌃⇧N to Reject) — you stay in control but don't have to reach for the mouse.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  How it actually works
&lt;/h2&gt;

&lt;p&gt;The app doesn't inspect the VS Code UI at all. Instead, it monitors Claude's own log files.&lt;/p&gt;

&lt;p&gt;Claude Code writes JSONL logs to &lt;code&gt;~/.claude/projects/&lt;/code&gt;. Every time Claude requests a tool use (edit a file, run a command, read a directory), it writes a &lt;code&gt;"type":"tool_use"&lt;/code&gt; entry with the specific tool name.&lt;/p&gt;

&lt;p&gt;The app polls these log files every 2 seconds, detects new tool use requests, and sends the appropriate keyboard event to VS Code to accept or reject them.&lt;/p&gt;

&lt;p&gt;The stack is straightforward macOS native:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AppKit&lt;/strong&gt; (NSStatusBar, NSMenu) for the menu bar app — no SwiftUI, just classic Cocoa&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CGEvent&lt;/strong&gt; for registering global hotkeys and sending keyboard events to VS Code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UserNotifications&lt;/strong&gt; for the summary notification when auto mode finishes&lt;/li&gt;
&lt;li&gt;File system monitoring for the JSONL logs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 2-second polling interval means there's a small delay between Claude asking for permission and the app accepting it. In practice, you barely notice it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The honest part: it's rough
&lt;/h2&gt;

&lt;p&gt;This started as an internal tool at our company. We use Claude Code daily to build &lt;a href="https://megify.ai" rel="noopener noreferrer"&gt;Megify&lt;/a&gt;, an AI platform that generates WordPress sites. We needed something that worked for us, not something polished for the world.&lt;/p&gt;

&lt;p&gt;It works. We use it every day. But:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multiple VS Code windows&lt;/strong&gt; can confuse it — it doesn't always target the right one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2-second polling&lt;/strong&gt; means occasional visible delay before acceptance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No prompt filtering&lt;/strong&gt; — in auto mode, it accepts everything. You can't say "auto-accept file edits but ask me about terminal commands"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;macOS only&lt;/strong&gt; — it uses native APIs that don't exist on Windows or Linux&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VS Code only&lt;/strong&gt; — no support for Claude Code in the standalone terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm open-sourcing it because every Claude Code user has the same problem, and I'd rather have 10 people improving it than try to polish it alone.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;You'll need macOS 13+ and Xcode command line tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xcode-select &lt;span class="nt"&gt;--install&lt;/span&gt;
git clone https://github.com/andreata/claude_vscode_accept_mac.git
&lt;span class="nb"&gt;cd &lt;/span&gt;claude_vscode_accept_mac
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x install.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Grant Accessibility permissions when prompted (System Settings &amp;gt; Privacy &amp;gt; Accessibility). The app needs this to send keyboard events to VS Code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shortcuts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;⌘⇧⌥0&lt;/strong&gt; — Accept current prompt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⌃⇧N&lt;/strong&gt; — Reject current prompt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fair warning: auto mode means Claude executes everything without asking. Use it on projects where you trust Claude's judgment, or use shortcut mode for more control.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I want to add (and need help with)
&lt;/h2&gt;

&lt;p&gt;The roadmap, roughly in priority order:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt filtering.&lt;/strong&gt; Auto-accept file edits and directory reads, but pause for terminal commands and destructive operations. This requires parsing the tool name from the JSONL entries and maintaining an allow/deny list. Most requested feature from my team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Better window targeting.&lt;/strong&gt; When you have 3 VS Code windows open, the app needs to send the keyboard event to the right one. Probably requires accessibility API inspection of the window hierarchy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt history/log.&lt;/strong&gt; A scrollable list in the menu bar dropdown showing what was accepted, when, and what tool was used. Useful for reviewing what Claude did while you were getting coffee.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Faster polling or file system events.&lt;/strong&gt; Replace the 2-second polling with FSEvents or DispatchSource.FileSystemObject for near-instant detection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terminal support.&lt;/strong&gt; Claude Code works in the regular terminal too, not just VS Code. The JSONL monitoring would still work, but sending the accept keystroke requires a different mechanism.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Homebrew formula.&lt;/strong&gt; &lt;code&gt;brew install claude-auto-accept&lt;/code&gt; would be the dream.&lt;/p&gt;

&lt;p&gt;If any of these interest you, PRs are very welcome. Even bug reports help — the more macOS versions and VS Code configurations we test against, the more reliable it gets.&lt;/p&gt;




&lt;h2&gt;
  
  
  The bigger picture
&lt;/h2&gt;

&lt;p&gt;The permission system in Claude Code exists for good reason — you don't want AI silently deleting files or running arbitrary commands. But the current UX is designed for safety, not productivity. Every developer who's been using Claude Code for months has muscle memory for "Accept" — the permission prompt is a speed bump, not a safety check.&lt;/p&gt;

&lt;p&gt;The right solution is filtering: auto-accept safe operations (read files, edit code, create files) and require confirmation for dangerous ones (delete files, run destructive commands, access network). That's what we're building toward.&lt;/p&gt;

&lt;p&gt;Until Anthropic adds this natively (please?), this menu bar app is the workaround.&lt;/p&gt;




&lt;p&gt;The repo: &lt;a href="https://github.com/andreata/claude_vscode_accept_mac" rel="noopener noreferrer"&gt;github.com/andreata/claude_vscode_accept_mac&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you use Claude Code daily and this sounds useful — or if you've built something similar — I'd love to hear about it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vscode</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Built a Headless WordPress Multisite Platform. It Worked Perfectly. Then the Server Bill Arrived.</title>
      <dc:creator>Andrea Tasselli</dc:creator>
      <pubDate>Mon, 16 Mar 2026 11:54:37 +0000</pubDate>
      <link>https://dev.to/andreata/i-built-a-headless-wordpress-multisite-platform-it-worked-perfectly-then-the-server-bill-arrived-2c68</link>
      <guid>https://dev.to/andreata/i-built-a-headless-wordpress-multisite-platform-it-worked-perfectly-then-the-server-bill-arrived-2c68</guid>
      <description>&lt;p&gt;This is a story about building something technically impressive that couldn't survive as a business. Everything worked. The architecture was solid. The client loved it. And we still had to abandon the model.&lt;/p&gt;

&lt;p&gt;If you're building platforms on top of WordPress — especially headless — this might save you six months of work.&lt;/p&gt;




&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;A few years ago, before AI-assisted development was a thing, my team and I set out to build a platform that would let anyone spin up a fully functional ecommerce store through a guided wizard.&lt;/p&gt;

&lt;p&gt;The pitch was simple: answer a few questions, pick a template, and get a live WooCommerce store with sample products, payment gateway configured, and a custom domain — all automated. No technical knowledge required.&lt;/p&gt;

&lt;p&gt;The twist: the frontend was headless. Every store ran a decoupled frontend that pulled data from WordPress via the REST API. The result was a shopping experience that felt like a native app — instant page transitions, snappy product filtering, smooth cart interactions. No full page reloads, no WordPress frontend overhead.&lt;/p&gt;

&lt;p&gt;We were proud of it. Rightfully so — it was a serious piece of engineering.&lt;/p&gt;




&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;p&gt;We ran everything on OVH Cloud with Docker. The core architecture:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WordPress Multisite&lt;/strong&gt; as the backend. Each new store was a subsite on the network. This gave us centralized plugin management, shared user tables, and a single WordPress installation to maintain. When we updated a plugin, every store got it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automated provisioning.&lt;/strong&gt; When a user completed the wizard, the system created the multisite subsite, pointed a domain via DNS API, installed WooCommerce with preconfigured settings, populated sample products and categories, and generated the headless frontend build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decoupled frontend.&lt;/strong&gt; Each store had its own static frontend (built with &lt;a href="https://gridsome.org" rel="noopener noreferrer"&gt;Gridsome&lt;/a&gt; — a Vue-based static site generator that was popular at the time) that consumed the WordPress REST API. This was pre-rendered and served from a CDN. Page loads were sub-200ms. Product pages felt instant. The checkout was smooth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker orchestration.&lt;/strong&gt; Everything ran in containers — the WordPress multisite, the database, Redis for object caching, Nginx as reverse proxy, and the build pipeline for the frontends.&lt;/p&gt;

&lt;p&gt;It was beautiful. It was fast. It worked.&lt;/p&gt;




&lt;h2&gt;
  
  
  The client
&lt;/h2&gt;

&lt;p&gt;We sold the platform to one of our agency clients. They wanted a way to offer ecommerce stores to their small business customers without building each one from scratch.&lt;/p&gt;

&lt;p&gt;They're still using it today — you can see the original platform at &lt;a href="https://megicart.it/" rel="noopener noreferrer"&gt;megicart.it&lt;/a&gt;. Their customers love the speed of the frontend. The admin is standard WooCommerce, so anyone can manage products and orders. Updates are centralized. Support is straightforward.&lt;/p&gt;

&lt;p&gt;One client, one multisite, a manageable number of stores. It works great in that context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where it broke
&lt;/h2&gt;

&lt;p&gt;The first client worked great. One store, manageable product catalog, builds running smoothly. We were confident.&lt;/p&gt;

&lt;p&gt;So we added two more test stores to the multisite to simulate what a real platform would look like. Three stores total on a €68/month OVH Cloud instance. Not a cheap server — decent specs, solid performance for most workloads.&lt;/p&gt;

&lt;p&gt;Then all three stores triggered builds around the same time. A product update on store one. A page edit on store two. A theme change on store three.&lt;/p&gt;

&lt;p&gt;The server froze. Completely. CPU pegged at 100%, memory exhausted, SSH unresponsive. We had to hard reboot from the OVH panel.&lt;/p&gt;

&lt;p&gt;Three stores. Not thirty. Not three hundred. Three.&lt;/p&gt;

&lt;p&gt;The problem was fundamental: a headless frontend needs to be built. Every time a store owner changes a product, updates a page, or modifies anything, the static frontend regenerates. That means pulling every product from the WordPress REST API, rendering every product page, every category page, every filtered view. For a store with hundreds of products, a single build consumes several GB of RAM and a full CPU core for minutes.&lt;/p&gt;

&lt;p&gt;One build at a time? Fine. Two or three concurrent builds on the same server? Everything dies.&lt;/p&gt;




&lt;h2&gt;
  
  
  The math that killed it
&lt;/h2&gt;

&lt;p&gt;We did the math we should have done before building the platform.&lt;/p&gt;

&lt;p&gt;To run just 10 stores without builds crashing each other, we needed a server with enough CPU and RAM to handle 3-4 concurrent builds. That meant upgrading to an instance 4-5x more expensive — €250-350/month minimum.&lt;/p&gt;

&lt;p&gt;For 50 stores, we'd be looking at €500-600/month in infrastructure alone. At that point, each store needs to pay €10-12/month just to cover servers. Add development, support, and margin, and the price per store hits €25-40/month.&lt;/p&gt;

&lt;p&gt;Meanwhile, a traditional WordPress site with good hosting (not headless, just well-optimized with caching and a CDN) delivers sub-500ms page loads at €5-8/month per site. The headless frontend was objectively faster — sub-200ms — but was that extra speed worth 4-5x the infrastructure cost? For a small business owner selling candles or running a restaurant menu? No.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we got wrong
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;We never tested concurrent builds before building the platform.&lt;/strong&gt; We tested one store, it worked, and we assumed three would work three times as well. That's not how shared server resources work. One build is fine. Three concurrent builds on the same machine is a completely different problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We optimized for the wrong metric.&lt;/strong&gt; We were obsessed with frontend performance (sub-200ms loads) without calculating whether that performance justified the infrastructure cost. A well-configured traditional WordPress site with a CDN delivers sub-500ms loads at a fraction of the cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multisite amplified the problem.&lt;/strong&gt; WordPress Multisite shares everything — database, PHP processes, memory. When one store triggers a heavy build, every other store on the network competes for the same resources. Isolated instances would have been more resilient, but then you lose the centralized management that made multisite attractive in the first place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We fell in love with the architecture.&lt;/strong&gt; The headless setup was technically beautiful. The frontend was objectively faster. The developer experience was great. But none of that matters if three stores crash a €68/month server. We kept trying to optimize the build pipeline instead of questioning whether headless was the right choice for this business model.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd do differently
&lt;/h2&gt;

&lt;p&gt;If I were building this today, I'd make three different choices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skip headless for this use case.&lt;/strong&gt; A traditional WordPress frontend with a good theme, proper caching, and a CDN delivers "fast enough" for small business ecommerce. The difference between 200ms and 500ms page loads doesn't move the conversion needle for a store selling artisanal candles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Isolated instances instead of multisite.&lt;/strong&gt; Each store gets its own containerized WordPress environment. No shared resources, no noisy neighbors, predictable performance. This is actually what I ended up building with &lt;a href="https://megify.ai" rel="noopener noreferrer"&gt;Megify&lt;/a&gt; — every generated site runs in its own isolated environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let AI handle the content generation.&lt;/strong&gt; Back then, we had to manually create templates and sample content for each store type. Today, AI generates unique designs, copy, and product structures from a text description. The provisioning that took us hours of template work now takes minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  The lesson
&lt;/h2&gt;

&lt;p&gt;The project wasn't a failure. One client is still happily using it years later. We learned Docker orchestration, headless WordPress architecture, API optimization, and build pipeline management. All of that knowledge directly informed what I'm building now.&lt;/p&gt;

&lt;p&gt;But the business model was flawed because we didn't do the infrastructure math until we'd already built the platform. By then, we were emotionally invested in the architecture and kept trying to make it cheaper instead of asking whether headless was the right approach for the market we were targeting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The takeaway: run the unit economics before you write the first line of code.&lt;/strong&gt; Especially for platform businesses where infrastructure costs scale with usage. The most elegant architecture in the world doesn't matter if you can't charge enough to pay for the servers.&lt;/p&gt;




&lt;p&gt;I'm now building &lt;a href="https://megify.ai" rel="noopener noreferrer"&gt;Megify&lt;/a&gt;, which evolved directly from that failed platform — even the name comes from &lt;a href="https://megicart.it/" rel="noopener noreferrer"&gt;MegiCart&lt;/a&gt;, the original headless project. Megify generates WordPress sites and ecommerce stores using AI. Traditional WordPress, not headless — because the infrastructure math works. Each site is isolated (not multisite), AI handles the content generation, and the hosting cost per site is predictable and sustainable. There's a &lt;a href="https://megify.ai/sito-wordpress-ai/" rel="noopener noreferrer"&gt;technical breakdown of the architecture&lt;/a&gt; if you're curious how it works under the hood.&lt;/p&gt;

&lt;p&gt;I also open-sourced a tool we built along the way: &lt;a href="https://github.com/andreata/figma-to-avada" rel="noopener noreferrer"&gt;Figma to Avada&lt;/a&gt; — converts Figma designs to WordPress/Avada shortcodes using AI.&lt;/p&gt;

&lt;p&gt;Sometimes the boring architecture is the right architecture.&lt;/p&gt;

&lt;p&gt;If you've had similar experiences — building something technically impressive that didn't survive contact with business reality — I'd love to hear about it.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>webdev</category>
      <category>startup</category>
      <category>devops</category>
    </item>
    <item>
      <title>Using LLMs to Generate Structured Data for WordPress (Not HTML)</title>
      <dc:creator>Andrea Tasselli</dc:creator>
      <pubDate>Fri, 13 Mar 2026 14:44:32 +0000</pubDate>
      <link>https://dev.to/andreata/using-llms-to-generate-structured-data-for-wordpress-not-html-23n</link>
      <guid>https://dev.to/andreata/using-llms-to-generate-structured-data-for-wordpress-not-html-23n</guid>
      <description>&lt;p&gt;Most tutorials about AI + web development show the same pattern: give the LLM a prompt, get back HTML, paste it somewhere. It works for prototypes. It breaks in production.&lt;/p&gt;

&lt;p&gt;I've been building a system that generates full WordPress sites from text descriptions. Early on, I made the obvious choice: have the AI generate HTML. It took about two weeks to realize that was a terrible idea.&lt;/p&gt;

&lt;p&gt;Here's what I learned, and the architecture I ended up with instead.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why generating HTML is a trap
&lt;/h2&gt;

&lt;p&gt;When you ask an LLM to generate a web page, it produces markup. Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hero-section"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #1a1a2e; padding: 80px 40px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color: white; font-size: 48px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Artisan Gelato&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color: #ccc;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Handcrafted flavors since 1987&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/menu"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #e63946;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;View Menu&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks fine. Now try to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Edit it with a visual editor.&lt;/strong&gt; Elementor, Gutenberg, or any page builder will choke on inline styles and non-standard class names. The user can't drag-and-drop edit something that wasn't built with the editor's data model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Update the theme.&lt;/strong&gt; When the theme updates, your generated HTML stays frozen in time. Fonts change, spacing changes, colors change — everywhere except your AI-generated sections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Make it responsive.&lt;/strong&gt; The AI generated desktop markup. Mobile? Tablet? You need media queries that reference the AI's arbitrary class names. Good luck maintaining that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep it consistent.&lt;/strong&gt; Generate 5 pages with 5 separate prompts. Each one uses slightly different class names, different heading hierarchies, different spacing values. There's no design system — just 5 independent HTML blobs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;HTML generation works for one-off demos. It doesn't work for production sites that need to be maintained, edited, and updated by non-technical users.&lt;/p&gt;




&lt;h2&gt;
  
  
  The alternative: generate data, not markup
&lt;/h2&gt;

&lt;p&gt;Instead of asking the AI to produce HTML, I have it produce a &lt;strong&gt;structured JSON schema&lt;/strong&gt; that maps to WordPress constructs.&lt;/p&gt;

&lt;p&gt;Here's the same hero section, but as structured data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"section"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"template"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hero"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"background_color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#1a1a2e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"padding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"top"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"bottom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"left"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"right"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"text_align"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"center"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"elements"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"heading"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Artisan Gelato"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tag"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"h1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"font_size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Handcrafted flavors since 1987"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#cccccc"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"View Menu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/menu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"background"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#e63946"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This JSON gets translated by a &lt;strong&gt;rendering layer&lt;/strong&gt; into whatever the target system needs — Elementor widgets, Gutenberg blocks, WooCommerce products, WordPress custom fields.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this works better
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The visual editor understands it
&lt;/h3&gt;

&lt;p&gt;When the JSON is translated into Elementor's data format, the result is a native Elementor section. The user opens the page builder and sees editable widgets — not a frozen HTML block. They can drag elements, change colors, edit text, exactly like any other Elementor page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JSON schema → Translator → Elementor data model → Native editable page
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The translator is a mapping layer that knows how to convert each JSON element type into its Elementor equivalent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"type": "heading"&lt;/code&gt; → Elementor Heading widget&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"type": "text"&lt;/code&gt; → Elementor Text Editor widget
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"type": "button"&lt;/code&gt; → Elementor Button widget&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"type": "section"&lt;/code&gt; with &lt;code&gt;"template": "hero"&lt;/code&gt; → Elementor Section with specific column structure&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Theme changes don't break anything
&lt;/h3&gt;

&lt;p&gt;The JSON doesn't contain theme-specific code. The translator reads the current theme's settings (fonts, colors, spacing defaults) and applies them during rendering. When the theme updates, the translator re-renders with the new settings. Nothing breaks.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Consistency is built in
&lt;/h3&gt;

&lt;p&gt;Every page goes through the same translator. The same &lt;code&gt;"type": "heading"&lt;/code&gt; always produces the same Elementor widget with the same base settings. No more five-pages-five-different-approaches problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The AI's job is simpler
&lt;/h3&gt;

&lt;p&gt;Generating valid JSON with a known schema is much easier for an LLM than generating valid, semantic, accessible, responsive HTML. The error rate drops dramatically.&lt;/p&gt;

&lt;p&gt;With HTML generation, about 8-12% of outputs had issues — unclosed tags, broken nesting, inaccessible markup. With JSON generation against a strict schema, the error rate is under 1%.&lt;/p&gt;




&lt;h2&gt;
  
  
  The prompt architecture
&lt;/h2&gt;

&lt;p&gt;Getting an LLM to produce reliable structured output requires more than "generate JSON." Here's the approach that works in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  System prompt: define the schema
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are a web architect. You generate website structures as JSON.

Every response must be valid JSON matching this schema exactly:
- Root: array of sections
- Each section: type, template, settings, elements
- Each element: type, content, style (optional), children (optional)

Valid section templates: hero, features, testimonials, pricing, 
  cta, gallery, team, faq, contact, footer
Valid element types: heading, text, button, image, icon, list, 
  card, column, spacer, divider, form

NEVER include HTML tags in content fields.
NEVER add properties not in the schema.
ALWAYS use the exact property names specified.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  User prompt: describe the project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generate a website structure for:
"Artisan gelato shop in Florence. Seasonal ingredients from 
local farms. Open since 1987. Need: homepage with hero, 
menu page, about page with our story, contact page."

For each page, generate the complete section structure 
with appropriate templates and real, relevant content.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key prompt engineering decisions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Temperature 0.5 for structure, 0.7 for content.&lt;/strong&gt; I actually make two passes. First pass: generate the page structure (which sections, which templates, how many elements) at low temperature for consistency. Second pass: generate the actual copy at slightly higher temperature for creativity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explicit constraints reduce errors.&lt;/strong&gt; "NEVER include HTML tags" catches the LLM's tendency to sneak in &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; tags inside content fields. "NEVER add properties not in the schema" prevents hallucinated fields that the translator doesn't know how to handle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Examples in the system prompt.&lt;/strong&gt; I include 2-3 examples of correctly formatted output. This alone reduced schema violations by ~60%.&lt;/p&gt;




&lt;h2&gt;
  
  
  WooCommerce: where structured data really shines
&lt;/h2&gt;

&lt;p&gt;For ecommerce, the gap between HTML generation and structured data is even bigger.&lt;/p&gt;

&lt;p&gt;An AI-generated WooCommerce product as HTML is useless — it's just text that looks like a product page. An AI-generated product as structured data actually creates a WooCommerce product:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pistachio Gelato - 500ml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Classic Flavors"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Made with Bronte pistachios..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GEL-PIST-500"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"weight"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stock_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"instock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"images"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"pistachio-gelato.jpg"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"500ml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allergens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tree nuts, Milk"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gets imported directly via the WooCommerce REST API. The product appears in the shop with all its data — price, SKU, categories, attributes — correctly set. The user can manage it from the standard WooCommerce dashboard.&lt;/p&gt;

&lt;p&gt;Compare that to generated HTML of a product card. What do you do with it? Paste it somewhere? It doesn't connect to inventory, it doesn't process orders, it doesn't show up in the WooCommerce product list.&lt;/p&gt;




&lt;h2&gt;
  
  
  The translator in practice
&lt;/h2&gt;

&lt;p&gt;The translator is the bridge between the AI's JSON output and WordPress. Here's a simplified version of how it works for Elementor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;json_to_elementor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Convert a JSON section to Elementor data structure.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;template_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;columns&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;min_height&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;features&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;columns&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;min_height&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;testimonials&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;columns&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;min_height&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pricing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;columns&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;min_height&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;element_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;heading&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;heading&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;# Elementor widget type
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text-editor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;button&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;button&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;icon&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;icon&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;template_map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;template&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;

    &lt;span class="n"&gt;elementor_section&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elType&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;section&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;settings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;background_color&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;settings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;background_color&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;padding&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;settings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;padding&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;min_height&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;size&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;min_height&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elements&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;  &lt;span class="c1"&gt;# Columns with widgets
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# Create columns and distribute elements
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elements&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;widget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elType&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;widget&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;widgetType&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;element_map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;settings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;translate_settings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;elementor_section&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elements&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;elementor_section&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actual production translator is more complex (handles nested elements, responsive settings, theme integration), but the principle is the same: &lt;strong&gt;map structured data to platform-native constructs.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Error handling
&lt;/h2&gt;

&lt;p&gt;Even with good prompts, LLMs occasionally produce invalid output. The system handles this with three layers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 1: JSON validation.&lt;/strong&gt; Parse the response. If it's not valid JSON, retry with the same prompt (up to 2 retries). This catches ~90% of failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 2: Schema validation.&lt;/strong&gt; Validate against the expected schema. If a required field is missing or a value is the wrong type, fill in sensible defaults rather than failing. A missing &lt;code&gt;font_size&lt;/code&gt; gets the theme default. A missing &lt;code&gt;background_color&lt;/code&gt; gets transparent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3: Rendering validation.&lt;/strong&gt; After the translator produces Elementor data, validate that the output is well-formed. Check for empty sections, orphaned elements, or invalid widget types. Remove anything that would break the page builder.&lt;/p&gt;

&lt;p&gt;In production, about 98.5% of generations succeed on the first attempt. Another 1% succeed on retry. The remaining 0.5% need manual review — usually because the AI generated content that's valid structurally but doesn't make sense contextually.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Some numbers from production:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;HTML generation&lt;/th&gt;
&lt;th&gt;JSON + translator&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Valid output rate&lt;/td&gt;
&lt;td&gt;~88%&lt;/td&gt;
&lt;td&gt;~98.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Editable in page builder&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Theme-compatible&lt;/td&gt;
&lt;td&gt;Fragile&lt;/td&gt;
&lt;td&gt;Fully&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Average generation time&lt;/td&gt;
&lt;td&gt;~45s&lt;/td&gt;
&lt;td&gt;~60s (two passes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User edit rate after generation&lt;/td&gt;
&lt;td&gt;~15%&lt;/td&gt;
&lt;td&gt;~65%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The last metric is the most telling. When users receive a generated page they can actually edit (because it's native Elementor), 65% of them make at least one modification. When they receive an HTML blob, only 15% try to change anything — most give up because they can't figure out how.&lt;/p&gt;

&lt;p&gt;The extra 15 seconds of generation time (for the two-pass approach + translation) is worth it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;If you're building anything that uses LLMs to generate web content for a CMS:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don't generate markup.&lt;/strong&gt; Generate structured data and translate it to the target platform's native format.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define a strict schema.&lt;/strong&gt; The tighter the schema, the more reliable the output. Give the LLM less room to improvise on structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use two passes.&lt;/strong&gt; Structure first (low temperature), content second (higher temperature). Mixing them in one pass increases both structural errors and content blandness.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build a robust translator.&lt;/strong&gt; The translator is where the real engineering lives. It needs to handle every edge case, fill defaults for missing values, and produce output that the visual editor treats as first-class.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Validate at every layer.&lt;/strong&gt; JSON parsing, schema validation, rendering validation. Each layer catches a different class of errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The AI generates the &lt;em&gt;what&lt;/em&gt;. The translator handles the &lt;em&gt;how&lt;/em&gt;. Keeping them separate is what makes the system reliable at scale.&lt;/p&gt;




&lt;p&gt;I've been running this architecture in production at &lt;a href="https://megify.ai" rel="noopener noreferrer"&gt;Megify&lt;/a&gt;, where we generate WordPress sites and WooCommerce stores from text descriptions. If you want to see how the structured data maps to actual WordPress constructs, there's a &lt;a href="https://megify.ai/sito-wordpress-ai/" rel="noopener noreferrer"&gt;technical overview here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy to answer questions about the schema design, prompt engineering, or the translation layer.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>wordpress</category>
      <category>llm</category>
    </item>
    <item>
      <title>I Open-Sourced a Figma-to-Avada Shortcode Converter (AI + Claude Code)</title>
      <dc:creator>Andrea Tasselli</dc:creator>
      <pubDate>Wed, 11 Mar 2026 16:52:50 +0000</pubDate>
      <link>https://dev.to/andreata/i-open-sourced-a-figma-to-avada-shortcode-converter-ai-claude-code-4fdn</link>
      <guid>https://dev.to/andreata/i-open-sourced-a-figma-to-avada-shortcode-converter-ai-claude-code-4fdn</guid>
      <description>&lt;p&gt;I  spent 14 hours last month converting a Figma design into Avada Builder shortcodes. Fourteen hours of matching padding values and clicking through dropdown menus.&lt;/p&gt;

&lt;p&gt;So I built a tool that does it with AI. Then I open-sourced it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/andreata/figma-to-avada" rel="noopener noreferrer"&gt;github.com/andreata/figma-to-avada&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The workflow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Export Figma frames as SVG&lt;/li&gt;
&lt;li&gt;Feed to Claude Code with optimized prompts&lt;/li&gt;
&lt;li&gt;Get back paste-ready Avada shortcodes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A page that took 14 hours manually now takes ~30 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it maps
&lt;/h2&gt;

&lt;p&gt;The conversion isn't random. SVG structure from Figma maps predictably to Avada's shortcode hierarchy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Figma frame (auto-layout: horizontal)
  └── Child 1 (width: 33%)          →  [fusion_builder_column type="1_3"]
  └── Child 2 (width: 66%)          →  [fusion_builder_column type="2_3"]
      └── Text layer "Heading"       →  [fusion_title size="2"]...[/fusion_title]
      └── Text layer "Body"          →  [fusion_text]...[/fusion_text]
      └── Rectangle (fill: #432df4)  →  background_color="#432df4"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Figma's auto-layout properties (padding, gap, direction) translate almost 1:1 to Avada's container settings. The AI reads these from the SVG attributes and generates the correct parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in the repo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Optimized prompts&lt;/strong&gt; — this is where the value is. Generic prompting gives you generic output. The prompts in &lt;code&gt;/prompts&lt;/code&gt; contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avada's complete shortcode syntax and parameter names&lt;/li&gt;
&lt;li&gt;Mapping rules from Figma properties to Avada settings&lt;/li&gt;
&lt;li&gt;Common patterns (hero sections, feature grids, pricing tables)&lt;/li&gt;
&lt;li&gt;Edge case handling (overlapping elements, absolute positioning)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prompt variants:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;full-page.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Entire page conversion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;single-section.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One section at a time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ecommerce.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;WooCommerce + Avada layouts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;responsive.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Mobile + tablet breakpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;theme-match.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Match existing Global Options&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt; — before/after for a restaurant page, portfolio, and WooCommerce store.&lt;/p&gt;

&lt;h2&gt;
  
  
  What works well
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Container/row/column structure with correct widths&lt;/li&gt;
&lt;li&gt;Typography (family, size, weight, line-height, spacing)&lt;/li&gt;
&lt;li&gt;Colors (backgrounds, text, borders from Figma color styles)&lt;/li&gt;
&lt;li&gt;Spacing (padding/margin calculated from the design)&lt;/li&gt;
&lt;li&gt;Avada-specific elements (buttons, pricing tables, testimonials, counters)&lt;/li&gt;
&lt;li&gt;WooCommerce grids&lt;/li&gt;
&lt;li&gt;Per-element custom CSS&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What doesn't work (yet)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Complex animations (Avada's animation system is limited anyway)&lt;/li&gt;
&lt;li&gt;Mega menus&lt;/li&gt;
&lt;li&gt;Dynamic content / conditional logic&lt;/li&gt;
&lt;li&gt;Designs that are 100% custom CSS with no Avada element equivalents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Realistically it covers 80-90% of the work. The remaining 10-20% needs human judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips for best results
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Name your Figma layers.&lt;/strong&gt; "hero-section" and "cta-button" give the AI context. "Frame 47" and "Rectangle 12" don't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use auto-layout.&lt;/strong&gt; The AI reads auto-layout properties directly. Without them, it has to guess the layout intent from absolute positions — which works but is less reliable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stick to Avada's grid.&lt;/strong&gt; Avada uses 1/6 columns. If your Figma uses a 12-column grid, the mapping is nearly perfect. Odd column widths require creative workarounds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Google Fonts.&lt;/strong&gt; If the font exists on Google Fonts, the AI generates the correct Avada typography settings automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The prompt engineering is the product
&lt;/h2&gt;

&lt;p&gt;I want to be transparent: the "tool" is really a set of well-crafted prompts + a workflow. There's no custom software, no API wrapper, no build step. It's Claude Code + structured prompts + SVG files.&lt;/p&gt;

&lt;p&gt;That's intentional. The AI does the heavy lifting. The prompts provide the domain knowledge. You provide the design. The combination is what makes it work.&lt;/p&gt;

&lt;p&gt;If you have better prompts for specific Avada elements or edge cases, PRs are very welcome. The more Avada-specific knowledge we encode in the prompts, the better the output gets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I open-sourced it
&lt;/h2&gt;

&lt;p&gt;The Figma-to-Avada conversion problem is universal in the WordPress agency world. Keeping this internal would save me hours. Open-sourcing it saves everyone hours. And selfishly, more users means more edge cases discovered, more prompt improvements contributed, and a better tool for everyone — including me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/andreata/figma-to-avada" rel="noopener noreferrer"&gt;github.com/andreata/figma-to-avada&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MIT license. Star it if it's useful.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you work with Avada and Figma, I'd love to know: how do you currently handle this conversion? Manual rebuild? Some other workflow? Curious how others approach it.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>WordPress in 2026: Why I Still Choose It Over Custom CMS (And When I Wouldn't)</title>
      <dc:creator>Andrea Tasselli</dc:creator>
      <pubDate>Mon, 09 Mar 2026 15:05:16 +0000</pubDate>
      <link>https://dev.to/andreata/wordpress-in-2026-why-i-still-choose-it-over-custom-cms-and-when-i-wouldnt-18pp</link>
      <guid>https://dev.to/andreata/wordpress-in-2026-why-i-still-choose-it-over-custom-cms-and-when-i-wouldnt-18pp</guid>
      <description>&lt;p&gt;I've built products on both sides. Custom CMS from scratch, headless architectures, static site generators, and WordPress. After three years of running a platform that generates WordPress sites programmatically with AI, I have opinions. Strong ones.&lt;/p&gt;

&lt;p&gt;This isn't a "WordPress is the best" post. It's a breakdown of when WordPress is the right engineering decision, when it's not, and why the answer in 2026 is different from what it was in 2020.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Case Against WordPress (Let's Get This Out of the Way)
&lt;/h2&gt;

&lt;p&gt;I'll start with the reasons NOT to choose WordPress, because I think intellectual honesty makes the rest more credible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The database schema is a mess.&lt;/strong&gt; &lt;code&gt;wp_posts&lt;/code&gt; stores pages, posts, attachments, revisions, menu items, and custom post types all in one table. &lt;code&gt;wp_postmeta&lt;/code&gt; is an EAV anti-pattern that makes queries slow at scale. If you're building something that needs to handle 500K+ records with complex filtering, you'll fight WordPress every step of the way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The plugin ecosystem is a double-edged sword.&lt;/strong&gt; 60,000 plugins sounds great until you realize that 90% of them are poorly maintained, inject inline styles everywhere, and load 14 JavaScript files on every page. Plugin conflicts are still the number one cause of WordPress sites breaking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHP.&lt;/strong&gt; I know, I know. PHP 8.3 is actually good. But if your team writes TypeScript all day and you're building a product from scratch, forcing them into PHP is a cost. Hiring PHP developers is harder than hiring JS developers in most markets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The admin UI shows its age.&lt;/strong&gt; Gutenberg improved things, but the WordPress admin still feels like a 2010 app compared to modern CMS dashboards. If your end users are developers or tech-savvy people, they'll notice.&lt;/p&gt;

&lt;p&gt;If any of these are dealbreakers for your specific project, stop reading and go build your custom CMS. Seriously. There's no shame in it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Still Choose WordPress (For Most Projects)
&lt;/h2&gt;

&lt;p&gt;Now here's why, despite all of that, I keep coming back.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Ecosystem Is the Product
&lt;/h3&gt;

&lt;p&gt;WordPress isn't a CMS. It's a platform with an ecosystem. And in 2026, that ecosystem is the moat.&lt;/p&gt;

&lt;p&gt;WooCommerce alone powers roughly 25% of all ecommerce stores. That means every payment gateway, every shipping provider, every accounting tool, every marketing platform has a WordPress integration. Not "we'll build one if you ask" — it exists, right now, maintained and documented.&lt;/p&gt;

&lt;p&gt;When I built &lt;a href="https://megify.ai" rel="noopener noreferrer"&gt;Megify&lt;/a&gt;, I evaluated building a custom CMS. The AI generation part would have been easier — I could design the data model from scratch, optimize every query, skip all the WordPress legacy cruft.&lt;/p&gt;

&lt;p&gt;But then I listed everything I'd need to rebuild:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ecommerce (products, cart, checkout, payments, shipping, taxes, refunds)&lt;/li&gt;
&lt;li&gt;SEO (sitemaps, meta tags, schema markup, redirects)&lt;/li&gt;
&lt;li&gt;Email integration (transactional, marketing, automation)&lt;/li&gt;
&lt;li&gt;Forms (contact, lead gen, multi-step)&lt;/li&gt;
&lt;li&gt;Analytics integration&lt;/li&gt;
&lt;li&gt;Caching and CDN&lt;/li&gt;
&lt;li&gt;User management and roles&lt;/li&gt;
&lt;li&gt;Media management and optimization&lt;/li&gt;
&lt;li&gt;Multilingual support&lt;/li&gt;
&lt;li&gt;Accessibility compliance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's not a CMS. That's a decade of work. WordPress gives you all of it, battle-tested at scale, for free.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Portability Is a Feature
&lt;/h3&gt;

&lt;p&gt;This is underrated and I'll die on this hill.&lt;/p&gt;

&lt;p&gt;When a user creates a site on Megify, they get a standard WordPress installation. Full admin access. SSH. SFTP. WP-CLI. Database access. They can install any plugin, any theme, export their entire site, and move it to literally any hosting provider on earth.&lt;/p&gt;

&lt;p&gt;If Megify disappeared tomorrow, their site would keep working.&lt;/p&gt;

&lt;p&gt;Try doing that with Wix. Or Squarespace. Or Webflow. Or any proprietary CMS.&lt;/p&gt;

&lt;p&gt;Portability isn't just a philosophical stance — it's a sales argument. When I tell a potential customer "the site is yours, no lock-in, you can leave anytime," the trust barrier drops dramatically. They're not buying into a platform. They're getting a WordPress site with AI superpowers.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Programmatic WordPress Is Underrated
&lt;/h3&gt;

&lt;p&gt;Here's what changed my mind about WordPress for product development: WP-CLI and the REST API.&lt;/p&gt;

&lt;p&gt;Most developers interact with WordPress through the admin panel. Click, click, click. It feels slow and manual because it is.&lt;/p&gt;

&lt;p&gt;But WordPress is fully programmable. Every operation — creating posts, configuring plugins, setting options, managing users — can be done via CLI or API. When you treat WordPress as a headless backend that you configure programmatically, the experience is completely different.&lt;/p&gt;

&lt;p&gt;Our generation pipeline doesn't touch the admin UI. It provisions a container, installs WordPress via CLI, configures plugins via CLI, creates pages and products via the REST API, and sets theme options via the database directly. The entire process takes 90 seconds and produces a fully configured site.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This is what "creating a WordPress site" looks like in 2026&lt;/span&gt;
wp core &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TITLE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--admin_user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
wp plugin &lt;span class="nb"&gt;install &lt;/span&gt;woocommerce elementor &lt;span class="nt"&gt;--activate&lt;/span&gt;
wp option update blogdescription &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TAGLINE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
wp rewrite structure &lt;span class="s1"&gt;'/%postname%/'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're evaluating WordPress and your mental model is "click through the admin panel," you're evaluating the wrong thing.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. WordPress + AI = The Complexity Problem Is Solved
&lt;/h3&gt;

&lt;p&gt;The number one argument against WordPress has always been complexity. "It's too hard for non-technical users."&lt;/p&gt;

&lt;p&gt;In 2026, this argument is dead.&lt;/p&gt;

&lt;p&gt;AI can generate the initial site (design, content, structure) from a text description. AI can handle ongoing modifications through natural language — "add a testimonials section," "change the color scheme," "create a new product category." The visual editor (Elementor, Gutenberg) handles everything else.&lt;/p&gt;

&lt;p&gt;The user never needs to see PHP, never needs to understand hooks and filters, never needs to configure a database. They get the full power of WordPress with an interface that's simpler than Wix.&lt;/p&gt;

&lt;p&gt;This is what we built with &lt;a href="https://megify.ai/sito-wordpress-ai/" rel="noopener noreferrer"&gt;Megify&lt;/a&gt; — and it's what I think the future of WordPress looks like for 80% of users. The platform stays powerful; the interface becomes invisible.&lt;/p&gt;




&lt;h2&gt;
  
  
  When I Would NOT Choose WordPress
&lt;/h2&gt;

&lt;p&gt;Being honest about limitations is more useful than cheerleading.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;High-performance web apps.&lt;/strong&gt; If you're building a SaaS dashboard, a real-time collaboration tool, or anything that needs sub-100ms response times with complex state management — don't use WordPress. Use Next.js, SvelteKit, or whatever your team is fastest with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer-facing products.&lt;/strong&gt; If your users are developers who expect Git-based workflows, preview deployments, and infrastructure-as-code — WordPress will frustrate them. Look at headless CMS options like Sanity, Strapi, or Payload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pure API backends.&lt;/strong&gt; If you just need a content API with no frontend, WordPress is overkill. A headless CMS or even a simple database with an API layer is cleaner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Very large content databases.&lt;/strong&gt; If you're dealing with millions of records that need complex querying and relationships, the wp_postmeta EAV pattern will be your enemy. Use a proper relational schema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When your team actively dislikes PHP.&lt;/strong&gt; Team happiness matters. If forcing WordPress on a team that hates PHP results in slower development and worse code quality, the ecosystem benefits aren't worth it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Decision Framework
&lt;/h2&gt;

&lt;p&gt;Here's the mental model I use in 2026:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose WordPress when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your project serves end users who need to edit content&lt;/li&gt;
&lt;li&gt;You need ecommerce (WooCommerce is unbeatable for SMB)&lt;/li&gt;
&lt;li&gt;SEO matters (WordPress SEO tooling is the best in class)&lt;/li&gt;
&lt;li&gt;Your users need to own their site (portability matters)&lt;/li&gt;
&lt;li&gt;You need integrations with third-party services&lt;/li&gt;
&lt;li&gt;Time to market matters more than architectural purity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Choose custom when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're building a product, not a website&lt;/li&gt;
&lt;li&gt;Performance requirements are extreme&lt;/li&gt;
&lt;li&gt;Your data model doesn't fit posts/pages/meta&lt;/li&gt;
&lt;li&gt;Your team has strong opinions about their stack (and they're right)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Choose headless CMS when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need content management + custom frontend&lt;/li&gt;
&lt;li&gt;Your team is frontend-focused (React/Vue/Svelte)&lt;/li&gt;
&lt;li&gt;You want Git-based content workflows&lt;/li&gt;
&lt;li&gt;Preview deployments are important&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  A Note on "WordPress at Scale"
&lt;/h2&gt;

&lt;p&gt;People love to say "WordPress doesn't scale." This is technically incorrect and practically misleading.&lt;/p&gt;

&lt;p&gt;WordPress.com (Automattic) serves billions of pageviews per month on WordPress. The White House website runs on WordPress. TechCrunch, BBC America, Bloomberg — all WordPress.&lt;/p&gt;

&lt;p&gt;What doesn't scale is cheap shared hosting + 47 unoptimized plugins + no caching. That's not a WordPress problem. That's an infrastructure problem.&lt;/p&gt;

&lt;p&gt;With proper hosting (containerized, with object caching, CDN, and database optimization), WordPress handles serious traffic without breaking a sweat. I've seen WordPress sites serve 50K concurrent users on a single optimized server.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;WordPress in 2026 is not the same product as WordPress in 2018. The Block Editor matured. The REST API is solid. PHP 8.x is genuinely fast. The hosting ecosystem (both traditional and managed) is excellent. And AI tools have eliminated the complexity barrier that kept non-technical users away.&lt;/p&gt;

&lt;p&gt;The real question isn't "is WordPress good enough." It's "do I need something different enough to justify building it myself?"&lt;/p&gt;

&lt;p&gt;Most of the time, the answer is no. And that's not a compromise — it's engineering pragmatism.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building something interesting with WordPress? Or deliberately chose not to? I'm genuinely curious about the decision frameworks other developers use. Drop a comment — especially if you disagree.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>wordpress</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I Built an AI-Powered System That Generates Full WordPress Sites in Under 5 Minutes</title>
      <dc:creator>Andrea Tasselli</dc:creator>
      <pubDate>Thu, 05 Mar 2026 11:16:59 +0000</pubDate>
      <link>https://dev.to/andreata/how-i-built-an-ai-powered-system-that-generates-full-wordpress-sites-in-under-5-minutes-2oo0</link>
      <guid>https://dev.to/andreata/how-i-built-an-ai-powered-system-that-generates-full-wordpress-sites-in-under-5-minutes-2oo0</guid>
      <description>&lt;p&gt;I've spent the last three years building infrastructure automation tools for WordPress deployments. Somewhere around project number 200, I realized I was solving the same problems over and over — and so was every other developer I knew.&lt;/p&gt;

&lt;p&gt;This post is a technical breakdown of how I built a system that automates the entire WordPress site generation pipeline: from server provisioning to AI-driven content scaffolding. No fluff, no hype — just architecture decisions, tradeoffs, and lessons learned.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Actual Problem (It's Not What You Think)
&lt;/h2&gt;

&lt;p&gt;The bottleneck in launching a WordPress site was never "creativity" or "design skills." It was the operational overhead.&lt;/p&gt;

&lt;p&gt;Here's what a typical client project looked like before automation:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Time spent&lt;/th&gt;
&lt;th&gt;Value added&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server provisioning + DNS&lt;/td&gt;
&lt;td&gt;30-60 min&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WordPress install + hardening&lt;/td&gt;
&lt;td&gt;20-30 min&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Theme install + child theme setup&lt;/td&gt;
&lt;td&gt;15-20 min&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plugin stack (SEO, cache, security, forms, analytics)&lt;/td&gt;
&lt;td&gt;30-45 min&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WooCommerce + payment gateway config&lt;/td&gt;
&lt;td&gt;45-60 min&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL + performance optimization&lt;/td&gt;
&lt;td&gt;20-30 min&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initial page structure + navigation&lt;/td&gt;
&lt;td&gt;60-90 min&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content creation (copy, images, meta)&lt;/td&gt;
&lt;td&gt;2-4 hours&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6-10 hours&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mostly low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pattern was obvious: 70-80% of the time went into tasks with zero or low creative value. The same stack, the same plugin configurations, the same performance tweaks — project after project.&lt;/p&gt;

&lt;p&gt;I started automating the zero-value tasks first. Then the low-value ones. Then I realized AI could handle the medium-value layer too.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

&lt;p&gt;The system has three layers, each handling a different part of the pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: Infrastructure Automation
&lt;/h3&gt;

&lt;p&gt;This is the foundation. When a new site is requested, the system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Provisions a containerized environment&lt;/strong&gt; with pre-optimized PHP, MySQL, and Nginx configurations. No shared hosting compromises — each site gets isolated resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deploys WordPress&lt;/strong&gt; with a hardened configuration: security headers, XML-RPC disabled, file editing disabled, auto-updates configured, database prefix randomized.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Installs and configures the plugin stack&lt;/strong&gt; programmatically via WP-CLI. The stack is opinionated but battle-tested: caching, SEO, security, backup, and performance monitoring — all pre-configured with sane defaults.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Handles SSL provisioning and DNS&lt;/strong&gt; automatically. No manual certificate management, no waiting for propagation.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The entire infrastructure layer completes in under 90 seconds. What used to take an hour of clicking through admin panels is now a single API call.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: AI Content Generation
&lt;/h3&gt;

&lt;p&gt;Once the WordPress environment is live, the AI layer takes over. This is where it gets interesting.&lt;/p&gt;

&lt;p&gt;The input is a natural language description of the project. Something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Artisan gelato shop in Florence. We use seasonal ingredients from local farms. We've been open since 1987. We need a menu, an about page, and online ordering."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From this, the system generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Site structure&lt;/strong&gt;: pages, navigation hierarchy, internal linking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy&lt;/strong&gt;: headlines, body text, CTAs, meta descriptions — all tailored to the business type and tone&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layout decisions&lt;/strong&gt;: which sections go where, what content patterns fit the business type (hero, features, testimonials, pricing, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WooCommerce configuration&lt;/strong&gt; (when applicable): product categories, sample products with descriptions and pricing, shipping zones, payment gateway selection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key architectural decision here was &lt;strong&gt;not&lt;/strong&gt; generating raw HTML or theme files. Instead, the AI outputs a structured JSON schema that maps to WordPress constructs (pages, blocks, custom fields, WooCommerce objects). This means the output is always valid WordPress data, not fragile markup that breaks on the next theme update.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3: Visual Editing + AI Iteration
&lt;/h3&gt;

&lt;p&gt;The generated site is fully editable through two interfaces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A drag-and-drop visual editor&lt;/strong&gt; for people who want direct control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A conversational AI interface&lt;/strong&gt; where users can request changes in natural language: "Make the hero section taller," "Add a testimonials section after the pricing," "Change the color palette to something warmer"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each AI edit produces a diff against the current state, so changes are reversible and auditable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Decisions and Tradeoffs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why WordPress (and not a custom CMS)?
&lt;/h3&gt;

&lt;p&gt;I get this question a lot. The short answer: ecosystem and portability.&lt;/p&gt;

&lt;p&gt;WordPress powers roughly 40% of the web. Its plugin ecosystem is unmatched. Users can install any of 60,000+ plugins, hire any WordPress developer, and migrate to any host. There's no lock-in.&lt;/p&gt;

&lt;p&gt;Building a custom CMS would have been faster to develop initially, but it would have created a walled garden. I wanted the opposite: generate the site with AI, then give users complete ownership. Full SSH access, full database access, full file system access. Export your site anytime and run it anywhere WordPress runs.&lt;/p&gt;

&lt;p&gt;The tradeoff is complexity. WordPress has quirks, legacy patterns, and a database schema that wasn't designed for programmatic generation. Working around these adds engineering cost. But the user value of "this is standard WordPress, you own it completely" outweighs the developer convenience of a custom system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Not Headless?
&lt;/h3&gt;

&lt;p&gt;Headless WordPress is great for teams with frontend developers. But my target users don't have frontend developers — they're small business owners, solo entrepreneurs, local shops. They need something that works out of the box, with a visual editor they can understand.&lt;/p&gt;

&lt;p&gt;A traditional WordPress setup with a good theme and block editor gives them exactly that. No build step, no deployment pipeline, no React hydration issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Model Selection
&lt;/h3&gt;

&lt;p&gt;I use Claude (Anthropic) for content generation. The reasoning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Instruction following&lt;/strong&gt;: when I need structured JSON output with specific schemas, Claude is remarkably consistent. Fewer parsing failures, fewer retry loops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long context&lt;/strong&gt;: site generation requires holding the full project context (business description, existing pages, style preferences, product catalog) in a single prompt. Large context windows matter here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality of copy&lt;/strong&gt;: the generated text reads like it was written by a human copywriter, not a language model. This matters because the output goes directly onto live websites.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I tried several models during development. The main differentiator wasn't "intelligence" — it was reliability of structured output at scale. When you're generating hundreds of sites per day, a 2% parsing failure rate means dozens of manual interventions.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Start with the boring stuff.&lt;/strong&gt; The infrastructure automation (the least exciting part) delivered the most value. Shaving 60 minutes off every deployment compounds fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI is a first draft machine, not a final product machine.&lt;/strong&gt; The generated sites are good — genuinely good — but they're starting points. The best results come from users who take the AI output and refine it. The system is designed for this: generate fast, iterate easily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WordPress is messy and that's fine.&lt;/strong&gt; I spent months trying to make WordPress "cleaner" before accepting that its messiness is a feature. The ecosystem exists because WordPress is flexible enough to be messy. Fighting it is a waste of time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real moat is the integration, not the AI.&lt;/strong&gt; Anyone can call an LLM API. The hard part is connecting AI output to real infrastructure: DNS, SSL, databases, payment gateways, email, caching, backups. That operational layer is where the actual engineering lives.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Benchmarks
&lt;/h2&gt;

&lt;p&gt;Some real numbers from the production system:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Time from request to live site&lt;/td&gt;
&lt;td&gt;&amp;lt; 5 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure provisioning&lt;/td&gt;
&lt;td&gt;~90 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI content generation&lt;/td&gt;
&lt;td&gt;~60-120 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WordPress configuration&lt;/td&gt;
&lt;td&gt;~30 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Average TTFB (after optimization)&lt;/td&gt;
&lt;td&gt;&amp;lt; 400ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lighthouse performance score (generated sites)&lt;/td&gt;
&lt;td&gt;85-95&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uptime (last 12 months)&lt;/td&gt;
&lt;td&gt;99.97%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Platform
&lt;/h2&gt;

&lt;p&gt;I've been running this system in production as &lt;a href="https://megify.ai" rel="noopener noreferrer"&gt;Megify&lt;/a&gt;. It's designed for small businesses, freelancers, and agencies who need to launch WordPress sites and ecommerce stores fast.&lt;/p&gt;

&lt;p&gt;A few things that might be relevant if you're building something similar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The AI site generation is exposed through a conversational interface — describe your project and the system builds it&lt;/li&gt;
&lt;li&gt;WooCommerce is fully supported: products, categories, payments (Stripe, PayPal), shipping&lt;/li&gt;
&lt;li&gt;Every generated site is standard WordPress with full admin access, SSH, SFTP, and WP-CLI&lt;/li&gt;
&lt;li&gt;There's a &lt;a href="https://megify.ai/sito-wordpress-ai/" rel="noopener noreferrer"&gt;technical breakdown of the WordPress integration&lt;/a&gt; if you want to see how the AI-generated output maps to WordPress constructs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Three things I'm working on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-model orchestration&lt;/strong&gt;: using specialized models for different parts of the pipeline (one for copy, one for layout decisions, one for SEO optimization). Early tests show 15-20% quality improvement over single-model generation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automated A/B testing&lt;/strong&gt;: the system generates variant pages automatically and routes traffic to measure conversion. The goal is sites that optimize themselves over time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Plugin-aware generation&lt;/strong&gt;: teaching the AI to understand and configure the 200 most popular WordPress plugins, so it can set up complex workflows (membership sites, booking systems, LMS) without manual configuration.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;If you're working on similar problems (AI + infrastructure automation, programmatic CMS generation, or WordPress tooling), I'd love to hear about your approach. The space is moving fast and there's a lot of room for different architectures.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>showdev</category>
      <category>wordpress</category>
    </item>
  </channel>
</rss>
