<?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: rob-kingsbury</title>
    <description>The latest articles on DEV Community by rob-kingsbury (@robkingsbury).</description>
    <link>https://dev.to/robkingsbury</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%2F3909773%2Faa7f8688-1aa2-40ed-889c-c912835fd416.png</url>
      <title>DEV Community: rob-kingsbury</title>
      <link>https://dev.to/robkingsbury</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/robkingsbury"/>
    <language>en</language>
    <item>
      <title>I got tired of explaining WordPress to my clients, so I built this</title>
      <dc:creator>rob-kingsbury</dc:creator>
      <pubDate>Sun, 03 May 2026 05:41:03 +0000</pubDate>
      <link>https://dev.to/robkingsbury/i-got-tired-of-explaining-wordpress-to-my-clients-so-i-built-this-4188</link>
      <guid>https://dev.to/robkingsbury/i-got-tired-of-explaining-wordpress-to-my-clients-so-i-built-this-4188</guid>
      <description>&lt;p&gt;The handoff call is always the same.&lt;/p&gt;

&lt;p&gt;I walk the client through their dashboard, they nod, I leave, and three days later I get a text: &lt;em&gt;"Hey, how do I add a blog post again?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I tried Loom videos. Nobody watched them. Wrote a Google Doc. Nobody opened it. Built a custom help tab right inside their WordPress admin. Still got the texts.&lt;/p&gt;

&lt;p&gt;So I built a stupid simple plugin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/kingsbury-labs/wp-client-tour" rel="noopener noreferrer"&gt;WP Client Tour&lt;/a&gt;&lt;/strong&gt; shows your client a guided tour the first time they log in, walking them through the actual pages they'll use. Then it disappears and never fires again unless they ask for a replay. The whole thing runs off a single JSON file you drop in a folder, no subscription required and nothing to install beyond the plugin itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61vmy9uxikn8epw6gve4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61vmy9uxikn8epw6gve4.gif" alt=" " width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Add a file to &lt;code&gt;tours/&lt;/code&gt;:&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"woocommerce-orders"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target_page"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin.php?page=wc-orders"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target_roles"&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;"shop_manager"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"trigger"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"auto_once"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"steps"&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;"selector"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#toplevel_page_woocommerce"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"right"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Your WooCommerce 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;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Everything for your store lives here."&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;The plugin scans that folder on every admin page load. If the file validates, the tour runs. A tour for &lt;code&gt;shop_manager&lt;/code&gt; won't fire for admins. Tours can span multiple pages and pick up exactly where they left off after navigating. The renderer is 15kB of vanilla ES6 with no jQuery involved, so nothing fights with your client's plugin stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not Shepherd.js?
&lt;/h2&gt;

&lt;p&gt;Shepherd and Intro.js are solid. I've used both. But they're built for product teams shipping their own apps, not for someone handing off a WooCommerce store to a restaurant owner who's never touched a CMS.&lt;/p&gt;

&lt;p&gt;This is WordPress-native. It knows about user roles and admin pages out of the box, with no custom integration work on your end.&lt;/p&gt;

&lt;h2&gt;
  
  
  There's an AI authoring option if you want it
&lt;/h2&gt;

&lt;p&gt;Point it at a real &lt;code&gt;wp-admin&lt;/code&gt; page, it screenshots the UI and produces a &lt;code&gt;tour.json&lt;/code&gt; ready to drop in. Works with Claude Code, Cursor, or ChatGPT. Each step gets a confidence flag so you know which selectors are worth double-checking. Useful, but the plugin works fine without it.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's free
&lt;/h2&gt;

&lt;p&gt;MIT licensed. I built it because I got tired of answering the same support calls after every handoff. If you've got a better way to handle this, I'd love to hear your take on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo:&lt;/strong&gt; &lt;a href="https://kingsbury-labs.github.io/wp-client-tour/" rel="noopener noreferrer"&gt;https://kingsbury-labs.github.io/wp-client-tour/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/kingsbury-labs/wp-client-tour" rel="noopener noreferrer"&gt;https://github.com/kingsbury-labs/wp-client-tour&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Full disclosure: I write code, not tech papers, and AI helped me put this post together. Don't beat me up, it's my first time being a human on the internet.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
