Overview
AutoVinted is a full-stack SaaS platform + Chrome extension that automates product listing for resellers on the Vinted second-hand marketplace. Power-sellers list dozens to hundreds of items, and Vinted offers no bulk-upload tool and no official public API — so every listing normally means filling the same form (title, description, price, category, brand, size, color, condition, photos) by hand.
AutoVinted turns that into a spreadsheet-and-click workflow. It is built as two independent apps that talk over a JWT-authenticated REST API:
- a Next.js 16 + React 19 dashboard where sellers prepare and manage listings in bulk, and
- a Chrome Manifest V3 extension that publishes those listings to Vinted automatically — including anti-bot (DataDome) evasion across all 26 Vinted country domains.
One principle drives the whole design
The dashboard is the single source of truth (all business logic + data), and the extension is a pure API consumer that never touches the database. This keeps the backend completely client-agnostic — the extension is the first client today, but a mobile app or CLI tomorrow could reuse the exact same REST API with zero backend changes.
1 · The Dashboard (Web App)
The dashboard is where sellers do all their preparation work — built on the Next.js 16 App Router with a clean, layered backend.
The dashboard home: linked Vinted accounts, subscription plan, and account status at a glance.
1.1 Bulk Listing with the Spreadsheet Editor
The centerpiece of the dashboard is an Excel-like spreadsheet editor (ReactGrid) that turns "list 100 items" from hours into minutes.
Creating a spreadsheet — pick a category and template, then the fields (system / required) are configured from Vinted's schema before the grid opens.
- Typed cells — text, number, dropdown, and checkbox columns.
- Backend-driven dropdowns — real Vinted brands, colors, sizes, and conditions.
- Per-row validation — each row is validated before it can be published.
- Auto-saving drafts — in-progress bulk listings are persisted continuously and never duplicated.
- Photo upload per row — including folder / zip import via ExcelJS + JSZip.
1.2 Listings Management
Once created, every listing lives in a TanStack-powered table with full row and bulk actions.
Listings table — publish, repost, duplicate, edit price, or delete, individually or in bulk.
Listings carry a full status lifecycle (draft → ready → published → archived), a repost/relist history, and a photo editor (crop, rotate, delete, reorder) backed by Cloudinary storage with metadata.
1.3 Layered Backend
Business logic never lives in route handlers or UI — it lives in domain services, so the same logic powers both the web UI and the extension's API.
auth
Users, libsodium-encrypted credentials, Vinted account linking, JWT issuing & refresh.
listings
Listing CRUD, bulk ops, repost history, and Vinted wardrobe sync.
catalog
Vinted category tree + attribute definitions + reference data (brands, colors, conditions, size groups).
templates & spreadsheet
Versioned per-category templates, plus spreadsheet drafts, row validation, and draft → listing conversion.
2 · The Chrome Extension
A Manifest V3 extension injects a floating React panel (rendered inside a Shadow DOM) onto Vinted pages and automates the listing process. This is the technically hardest part of the project.
The extension's floating Shadow-DOM panel, running directly on a live Vinted page.
2.1 Three Build Targets
Chrome MV3 runs code in three isolated JavaScript contexts, so Vite builds three separate bundles:
| Target | Runs in | Job |
|---|---|---|
| background | Service worker | Message router; makes all dashboard API calls; downloads photos CORS-safely |
| content | Isolated world | Renders the React UI and drives Vinted's DOM/form |
| ddInterceptor | MAIN world, document_start | Anti-bot (DataDome) evasion — must load before Vinted's own scripts |
The core design constraint
The background context may never call Vinted (CORS), and the content context
may never call the dashboard (CORS). The content script always relays through
the background via chrome.runtime.sendMessage. This CORS boundary shapes the
entire extension.
2.2 The 12-Step Automated Publish Flow
The heart of the automation — it recreates a listing on Vinted exactly as a human would, but programmatically.
Prepare & navigate
Anti-bot / DataDome evasion runs first, then the extension fetches the listing data from the dashboard API and navigates to Vinted's listing form.
Fill & build the draft
It fills system fields (title, description, price), selects the category from Vinted's catalog, fills dynamic attributes (brand, size, color, condition, material…), and creates the draft on Vinted.
Upload, submit & report back
Photos are downloaded via the background worker (CORS-safe) and uploaded to
the draft, the listing is submitted, the published item ID + URL are
extracted, and the result is reported to the dashboard (mark-published).
2.3 Repost & Relist
Beyond first-time publishing, the extension can repost existing items to bump them back to the top of Vinted's search — with photo and title modifications and a full repost history.
The extension's Repost panel — modify photos and titles, apply price reductions, and review the repost history, all on the live Vinted page.
2.4 Anti-Bot Engineering (the standout piece)
Vinted is protected by DataDome, which blocks naive automation instantly. The extension defeats this with:
- DataDome challenge interception and response in the MAIN world.
- Synthetic but human-realistic mouse, keyboard, scroll, and click simulation.
- Relay telemetry events matching Vinted's expected behavioral patterns.
- Randomized human-like delays between every action, and CSRF token extraction.
- Per-domain dynamic DataDome endpoint resolution (all 26 countries).
All of this is deliberately isolated inside modules/vintedSession/ to contain the blast radius when Vinted updates its defenses.
3 · The Design (Figma)
The entire product was designed in Figma before implementation — covering the auth flows, the dashboard, the listing/spreadsheet section, the extension UI, and a shared design system.
The AutoVinted Figma file — auth, dashboard, listing section, extension, and design system.
The design system defines the shared visual language — the teal Autovinted brand, typography, spacing, and reusable components — so the dashboard and the extension feel like one product across two very different runtimes (a full web app vs. a Shadow-DOM overlay on someone else's page).
System Architecture
Technology Stack
Dashboard (Web App)
Next.js 16 (App Router, Server Actions), React 19, TypeScript 5, Tailwind CSS 4, shadcn/ui, Zustand, React Hook Form, and Zod.
Backend & Data
MongoDB via Mongoose, JWT (jose / jsonwebtoken) in HTTP-only cookies, bcrypt, Cloudinary media, and libsodium-encrypted credential storage.
Chrome Extension
Chrome Manifest V3 (service worker + content scripts), React 19 in a Shadow DOM overlay, TypeScript 5.9 (strict), Vite 8, Zustand, and Zod.
Spreadsheet & I/O
@silevis/reactgrid (spreadsheet editor), TanStack Table, ExcelJS, and JSZip for photo folder / zip import.
Project Structure
Frequently Asked Questions
See it in action
Explore the seller dashboard at the Live Application to see the bulk spreadsheet editor, listings management, and multi-account workflow.
