A plumber’s website usually ends up running three plugins: one for the contact form, one to lay out services and testimonials, one for local business schema. None of them knows about the others. So the alert that lands in the owner’s inbox says a form was submitted, and leaves out the thing they actually want to know, which job the caller is asking about.
Flexa Local Services is those three jobs in one plugin, wired together. The form knows which page it was sitting on, so every lead arrives labelled “Emergency Plumbing” or “Drain Cleaning” rather than “Contact form”. Hitting reply on the alert email goes to the customer, not to the website. Both of those are small things that decide whether the owner keeps the plugin after week one.
Everything lives under one Flexa Local menu: the content you publish, the leads that come in, the forms that collect them, and the settings they share.
An empty plugin is hard to judge. Pick a trade on the Tools screen, press Import, and you get a worked example of a whole site: home, services, pricing, service areas, recent work, reviews, about, FAQ, contact and a quote page, each one assembled from the blocks. Plumbing, electrical, HVAC, roofing and locksmith get an emergency call-out page as well, because those are the trades whose customers go looking for one at midnight.
Behind the pages sit six services with starting prices, six service areas, six testimonials, eight FAQs, three team members, three finished jobs, three offers and a quote form wired to the leads table.
Nine trades are there to pick from: plumbing, electrical, HVAC, roofing, locksmith, appliance repair, pest control, cleaning and landscaping. Everything is sample text about an invented company in Portland, written to be plausible rather than impressive, so edit the prices and the phone number before you launch. No images are bundled.
The pages arrive as drafts, so nothing shows up on your site until you publish them.
Publishing is one tick, and two more sit next to it: Home becomes the front page of the site, and a navigation menu is built from the page set and hung in the first free slot your theme offers. Both are on by default, and both need the pages published, so they sit out an import that comes in as drafts. The company name, phone, email and address are filled in from the sample data either way, but only where you have not set them yet. Nothing you already filled in is overwritten, and a menu your theme is already showing is left where it is. On a block theme the menu is still created, ready to drop into a Navigation block.
One button on the same screen takes the whole import back out again, by ID. The front page setting and the menu location go back the way they were, anything you edited in the meantime is kept, and no lead is ever touched.
Each one is a normal WordPress post type, so the editor, revisions, featured images and search all behave the way you expect.
Twelve blocks render your content on the front end. They are server rendered, so a published page always shows the current data, not a copy frozen at the time you saved it.
Services Grid, Areas Grid, Projects, Testimonials, Team, FAQ, Coupons, Pricing, Hero, CTA, Contact Card and Form.
Build a form in the Forms screen, drop the Form block (or the [flexa_local_form id="1"] shortcode) on any page, and submissions land in the Leads screen.
fxlc/v1 for content, forms, entries, leads and settings.fxlc_lead_notification, fxlc_form_spam_check, fxlc_form_public_submit, fxlc_settings_defaults, fxlc_admin_menu, fxlc_demo_packs, fxlc_demo_pages and more.One file in this plugin is compiled: the admin app bundle under
assets/dist/, built from apps/admin/src/ (TypeScript and React). The
readable source ships inside the plugin, next to the build it produces, so
nothing has to be fetched to inspect or rebuild it.
Everything else is already readable as shipped. assets/js/*.js and
assets/css/*.css are hand-written, with no build step and no minified
variant, and all of the PHP is plain source under app/.
To rebuild the bundle from the shipped source, in the plugin folder:
npm install -g pnpm).pnpm installpnpm buildThat runs TypeScript against apps/admin/tsconfig.json and then Vite against
apps/admin/vite.config.ts, writing the bundle and its manifest back into
assets/dist/. The plugin reads assets/dist/.vite/manifest.json to find the
hashed filenames, so a rebuild needs no change in PHP. pnpm type-check and
pnpm test run the type checker and the unit tests on their own.
The build tools are pinned in the package.json and pnpm-lock.yaml that ship
with the plugin: Vite 6, TypeScript 5, React 18, Tailwind CSS 4.