Anti-Lost is a Nuxt-based web application for creating dynamic QR pages for personal belongings. Instead of printing a static label with fixed contact details, the owner prints one QR code and keeps updating the destination page over time. When an item is safe, the page can stay minimal. When the item is lost, the same QR code can immediately switch into a recovery page with contact actions, a custom message, and a finder report form.
The project is designed for everyday items such as luggage, backpacks, keys, electronics, bikes, or work equipment. The core idea is simple: a printed QR code should not become outdated after the first day it is used.
Traditional lost-and-found tags have two common problems:
- They expose too much information all the time.
- They are static, so the printed label cannot adapt when the item status changes.
Anti-Lost addresses that by giving each item a permanent public URL at /s/:id. The owner manages the item from a private dashboard, while the person who scans the QR code sees a public page that reflects the latest state of the item.
- Sign in with Google and create a personal dashboard.
- Register multiple items and assign each one a persistent public QR page.
- Generate styled QR codes and download them as images for printing.
- Switch an item between
NORMALandLOSTstatus without changing the QR code URL. - Show or hide owner contact details depending on the item state.
- Add a custom lost message for the public recovery page.
- Let finders submit a contact message through the public page.
- Store finder reports in the dashboard for later review.
- Send Feishu webhook notifications when a finder submits a report.
- Support multiple UI languages: English, Simplified Chinese, Japanese, and Korean.
- The owner signs in with Google.
- The owner creates an item from the dashboard.
- The system generates a public page for that item at
/s/:id. - The owner downloads and prints the QR code.
- When someone scans the QR code:
- In normal mode, the page can stay low-profile and optionally show contact details.
- In lost mode, the page highlights that the item is lost, shows recovery actions, and allows the finder to send a message.
- The owner receives the finder report in the dashboard and can optionally receive a Feishu notification.
- View all registered items.
- Open a detail page for each item.
- Edit item metadata such as name and description.
- Toggle between safe and lost states.
- Configure contact email, phone number, lost message, and Feishu webhook URL.
- Review recent finder reports.
- Delete items that are no longer needed.
- Accessible without authentication.
- Shows item name, description, and owner name.
- Only exposes a limited subset of fields.
- Supports direct contact actions such as phone and email when enabled.
- Includes a report form so a finder can leave contact information and a message.
This project intentionally separates private ownership data from public recovery data.
- The public API only exposes a restricted item payload.
- The owner's email is not exposed on the public page by default.
- Contact fields can be shown conditionally based on the item state.
- Session-protected dashboard routes are guarded by middleware and server-side session checks.
- Nuxt 4
- Vue 3
- TypeScript
- Tailwind CSS
@nuxtjs/i18nfor localizationvee-validate+zodfor form validationvue-sonnerfor toast notificationslucide-vue-nextfor icons
- Reka UI primitives
- Local reusable UI components under
components/ui qr-code-stylingandqrcode.vuefor QR generation and export@vueuse/corefor clipboard and utility composables
- Nuxt server routes under
server/apiandserver/routes nuxt-auth-utilsfor session handling and OAuth helpers- Google OAuth for authentication
- Prisma ORM for data access
- The project is intended to be deployed and managed through Vercel
- Runtime environment variables are expected to be controlled from the Vercel project configuration
- Database credentials can be provisioned through Vercel-managed storage or environment settings, while the application itself consumes them through Prisma
- PostgreSQL as the primary database
- Prisma schema and migrations under
prisma/ - The application connects to the database through Prisma using
DATABASE_URL - In production, the active database connection is expected to be managed from Vercel project settings
- The sample environment configuration is set up for Prisma Postgres, which is the third-party hosted PostgreSQL service shown in
.env.example .env.examplealso includesPRISMA_DATABASE_URL, which indicates intended compatibility with Prisma Accelerate-style connection routing
- Google OAuth for login
- Feishu bot webhook for lost-item notifications
- Prisma Postgres as the external database service referenced by the project configuration
The main entities are:
User: account profile, default contact info, and default Feishu webhookProduct: the tracked item, including status, public contact fields, and recovery messageReport: finder-submitted messages associated with an itemAccount,Session, andVerificationToken: authentication/session models used by the login flow
.
|-- pages/ # Public pages and dashboard pages
|-- components/ # Reusable Vue components
|-- server/api/ # Authenticated and public API endpoints
|-- server/routes/ # OAuth route handlers
|-- prisma/ # Prisma schema and SQL migrations
|-- i18n/translations/ # Localized strings
|-- assets/css/ # Global styles
|-- public/ # Static assets
Create a local .env file based on .env.example.
For deployed environments, manage the same variables in Vercel rather than committing secrets to the repository.
Required or commonly used variables:
DATABASE_URL: PostgreSQL connection string. The example points to Prisma Postgres.PRISMA_DATABASE_URL: included in the sample env for Prisma Accelerate / data proxy style routing.NUXT_SESSION_PASSWORD: session secret used bynuxt-auth-utils.NUXT_OAUTH_GOOGLE_CLIENT_ID: Google OAuth client ID.NUXT_OAUTH_GOOGLE_CLIENT_SECRET: Google OAuth client secret.
Additional variable used by the notification flow:
AUTH_ORIGIN: base URL used to build dashboard links inside Feishu notifications.
Note: nuxt.config.ts also reads GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET into runtime config. If you standardize the environment setup later, keep the README and config aligned.
Before publishing the repository, verify the following:
- Do not commit
.env,.env.local, or any exported Vercel environment files. - Do not commit production database URLs, Prisma API keys, OAuth client secrets, session secrets, or Feishu webhook URLs.
- Remove one-off debug scripts, sample IDs, or logs that reference live data.
- Rotate credentials if they were ever shared outside your own machine or a trusted Vercel project.
- Review Vercel project members and environment variables before making the repository public.
- Keep
.env.examplelimited to placeholders only.
At the time of writing, the repository is structured correctly for open source as long as secrets remain outside version control and deployment credentials stay in Vercel project settings.
The fastest way to self-host this project privately is to use Vercel as the control plane and keep the repository private.
- Fork the repository or import it into your own private Git provider namespace.
- Create a new Vercel project from that private repository.
- Provision a PostgreSQL database through Vercel Storage or connect an external PostgreSQL instance.
- Add the required environment variables in Vercel:
DATABASE_URLNUXT_SESSION_PASSWORDNUXT_OAUTH_GOOGLE_CLIENT_IDNUXT_OAUTH_GOOGLE_CLIENT_SECRETAUTH_ORIGIN
- If you keep the current runtime config shape, also mirror the Google OAuth values into
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET, or remove that extra config path. - In Google Cloud Console, create your own OAuth app and set the authorized redirect URI to match your deployed
/auth/googleflow. - Optional: add a Feishu bot webhook if you want owner notifications for finder reports.
- Deploy the app. The build script already runs
prisma generate,prisma migrate deploy, andnuxt build. - After deployment, sign in once with your own Google account to bootstrap the first user record.
For local private deployment outside Vercel, the same environment variables still apply. The only mandatory infrastructure dependency is a PostgreSQL database reachable by Prisma.
Install dependencies:
bun installYou can also use npm, pnpm, or yarn, but the repository currently includes a bun.lock file.
Set up the database:
npx prisma migrate devStart the development server:
bun run devThe app runs at http://localhost:3000 by default.
Build the application:
bun run buildThe current build script runs:
prisma generate && prisma migrate deploy && nuxt buildPreview the production build locally:
bun run previewFor production deployment, Vercel should be treated as the source of truth for environment configuration and connected storage resources.
/: marketing / landing page/dashboard: authenticated item list/dashboard/products/:id: item management page/s/:id: public recovery page for a QR code/auth/google: Google OAuth entry point
This repository already covers the full core loop of a QR-based lost-and-found product:
- account login
- item creation and editing
- public recovery pages
- finder reporting
- notification hook integration
If you want to expand it, the most natural next steps are printable label templates, richer notification channels, better admin tooling, and analytics around scans and recovery events.



