HAP
All work04 / 09

AI & Automation

PopPublic — Marketplace Autofill Extension

Sellers who list the same item on Facebook Marketplace, Craigslist, and Nextdoor retype the same title, price, description, and photos into three different forms. PopPublic keeps your listing catalog in Supabase and drives each marketplace's own posting page through content scripts — filling fields by their real selectors, walking Craigslist through its multi-page wizard, and pushing your photos straight onto the file input. It deliberately stops before submitting so you stay in control of the final Post.

Stack

TypeScriptChrome Manifest V3React 18Supabase (Auth + Postgres + Storage)ViteVercel Serverless (heic-convert)browser-image-compression

Concepts

Cross-site DOM automationPer-marketplace field mappingService worker message passingProgrammatic file-input uploadSupabase auth + catalog

How it works

The whole flow, traced from your first tap.

React side panelBackground service workerContent scriptMarketplace DOMSupabase + Vercel API
  1. 01

    React side panel + Supabase

    Save a listing once

    You sign in and enter title, price, description, condition, and photos in the side panel. The listing is written to Postgres and images upload to the listing-photos bucket, so the same item is ready to post anywhere without retyping.

    React 18Supabase AuthPostgresSupabase Storage
  2. 02

    Side panel + Vercel API

    Drop in iPhone HEIC photos

    The uploader detects HEIC/HEIF files and posts them to a serverless convert-heic endpoint — trying a local dev server first, then Vercel — so they become web-safe JPEGs before any marketplace ever sees them, instead of being rejected at upload.

    heic-convertbrowser-image-compressionFileReader base64
  3. 03

    Side panel

    Pick a category once, get all three

    Choosing one category auto-fills the equivalent Facebook, Nextdoor, and Craigslist categories from a reviewed cross-platform map, with alias handling and a per-site fallback, so you never re-classify the same item three times.

    Override mapping tableText normalizationAliases
  4. 04

    Side panel + content script

    Open the marketplace and hit Autofill

    The panel checks which marketplace the active tab is on and sends the matching action to the content script, which already knows that site's selectors and form quirks.

    activeTab detectionchrome.tabs.sendMessageAction routing
  5. 05

    Content script + Marketplace DOM

    Watch the form fill itself

    Fields are found by visible label text and aria attributes and filled with synthetic input/change/blur events so React-based forms register them; on Craigslist the script walks the whole multi-page wizard, detecting which step it landed on and clicking through post-an-ad, for-sale-by-owner, and category selection.

    Label/aria selectorsSynthetic input eventsCraigslist wizard stepping
  6. 06

    Content script + background worker

    Photos land on the upload box

    Stored photos are fetched and attached to the page's file input via a DataTransfer object; for Craigslist's stricter CSP, the content script fetches the image bytes and the background worker rebuilds the files in the page's MAIN world and sets them on the uploader. Then it stops — you review everything and click Post yourself.

    DataTransfer injectionbase64 byte relayMAIN-world scripting

The problem

Each marketplace has a different posting form, different category taxonomy, and different photo uploader, so cross-posting one item means three rounds of copy-paste plus re-uploading the same images. There is no shared format, and Facebook's React form and Craigslist's multi-step wizard fight any naive automation.

What we built

A Manifest V3 extension with a React side panel backed by Supabase: you create a listing once (title, price, description, condition, photos, per-platform categories) and it is saved to Postgres with images in Supabase Storage. From the listing list you pick a target site; the side panel detects the active tab's platform and dispatches the right autofill routine via chrome.tabs.sendMessage to a content script that knows that site's DOM. Permissions are scoped to facebook.com, craigslist.org, and nextdoor.com only.

Per-site DOM automation and field mapping

Each platform has its own module compiled into one content script. Facebook fields are located by visible label text and aria-label and filled with synthetic input/change/blur events so React registers them; the category dropdown is opened last for a manual pick because Facebook's taxonomy is finer than ours. Craigslist is driven through its whole wizard — clicking post an ad, selecting for-sale-by-owner, choosing a category from a numeric-code map, then filling title and body — with logic detecting which step the page is on. A reviewed override table translates one chosen category into the matching Facebook, Nextdoor, and Craigslist categories at once, with normalization, aliases, and per-platform fallbacks.

Outcome

One saved listing populates three different marketplace forms — fields, photos, and categories — leaving only the final review and Post to the seller. HEIC photos from iPhones are converted to JPEG before they ever reach a marketplace, and the extension stays scoped to just the three supported sites.

Interested in something similar?

Tell us what you need and we'll figure out how to ship it.

Get in touch