This is a submission for Weekend Challenge: Earth Day Edition
Before It Becomes Trash — Helping Everyday Objects Get a Second Chance
What I Built
For this Earth Day challenge, I wanted to build something practical.
A lot of sustainability projects focus on awareness, visualization, or habit tracking. I wanted to focus on a smaller but very real moment: standing in front of a damaged object and not knowing whether it should be repaired, reused, recycled, or thrown away.
That is what Before It Becomes Trash is built for.
It is a circular economy web app that helps users decide what to do with everyday damaged objects before discarding them. A user can describe an item, upload an image, and receive a structured recommendation powered by AI. The app then helps turn that recommendation into a concrete rescue action and stores the result in a persistent user history.
Instead of treating sustainability as a distant global concept, I wanted to turn it into a local, personal decision support tool.
Core actions supported by the app:
- create and analyze an item
- upload an image to enrich the evaluation
- receive a structured recommendation: repair, reuse, recycle, or discard
- save rescue actions to a personal history
- earn badges for successful rescues
- record a symbolic badge memo on Solana Devnet
- use the interface in multiple languages
- explore a public demo flow without logging in
Demo
Live App: before-it-becomes-trash.vercel.app
Public Demo for Judges: before-it-becomes-trash.vercel.app/demo
I also created a public /demo route so judges can review the experience without creating an account. It uses mock data, but preserves the same visual flow and core interaction structure as the main app.
That was an intentional product decision: I wanted the judging experience to be quick and frictionless while still keeping the real authenticated app architecture in place.
Code
GitHub Repository: github.com/brandon0405/Before-It-Becomes-Trash
The repository contains the full implementation, including the authenticated flow, demo mode, AI analysis pipeline, Supabase persistence, internationalization, and Solana memo integration.
How I Built It
I built the app with a full-stack approach using a modern TypeScript-based architecture.
Product approach
My goal was not to build another generic “eco app.” I wanted to build a tool that answers one very practical question:
What should I do with this object before I throw it away?
That led to a product centered on decision support for damaged objects, not just environmental awareness.
Technical architecture
The app is built with:
- Next.js 14 with App Router
- TypeScript
- Tailwind CSS
- Auth0 for authentication
- Supabase for persistence
- Google Gemini for structured multilingual analysis
- Solana Devnet for symbolic badge memos
- zod for validation
Database design
I used Supabase to persist the main entities of the application:
profilesitemsanalysesrescue_actionsbadgesblockchain_records
This separation helped keep the logic clear between:
- the original object
- the AI-generated analysis
- the final rescue action
- the badge and symbolic blockchain record
AI analysis
Gemini is used to generate structured recommendations rather than purely conversational output.
That was important because the UI needs reliable categories and displayable fields, not just a paragraph of text. The model is used to help determine whether an object should be repaired, reused, recycled, or discarded, while also generating supporting reasoning.
The app also supports multilingual analysis, which matches the multilingual UI.
Internationalization
One part I especially wanted to push further was language support.
Something that bothered me about the other proposals was that they were only in English. As a Spanish speaker, I felt compelled to internationalize the site so that as many people as possible could use it.
The app includes a custom i18n implementation with 7 languages, plus RTL support for Arabic. That meant thinking beyond translated strings and handling direction-aware layouts properly.
Demo mode
Since full-stack challenge apps can be harder to evaluate when login is required, I added a public /demo route with mock data and the same visual flow pattern as the authenticated experience.
That gave me a better balance between:
- a real app architecture
- and a judge-friendly review experience
This is a strong place to show the form where the user enters object details and uploads an image.
Real user flow
The authenticated flow looks like this:
- The user signs in with Auth0
- The user creates a new item
- The user enters a description and optionally uploads an image
- The payload is validated with zod
- Gemini generates a structured evaluation
- The UI displays a recommendation
- The analysis is stored in Supabase
- The user saves a rescue action
- A badge can be awarded
- A symbolic memo is recorded on Solana Devnet
To keep the blockchain layer honest and lightweight, I used Solana Devnet to record a symbolic memo tied to rescue badge events. It is not the core of the product, but a verifiable trace of positive circular actions.
For judges, the /demo route offers a no-login path through essentially the same product story.
This should show the recommendation card clearly, ideally with one of the four outcomes visible.
Technical challenges I ran into
1. Making AI output reliable enough for the UI
A free-form AI answer is not ideal when the app needs structured fields.
I solved that by designing the Gemini integration around structured output and validating the incoming data before rendering. This made the analysis much more stable and usable in the interface.
2. Preventing duplicate saves
Saving the same action twice is easy to do when users retry or click again after a delay.
To avoid noisy records, I added duplicate prevention and explicit 409 conflict handling when appropriate.
3. Handling AI failures gracefully
I did not want the whole app to feel broken if the AI call failed.
So I implemented a robust fallback path, allowing the application to degrade gracefully instead of collapsing the user experience.
4. Making the app usable in multiple languages
Supporting seven languages, plus Arabic RTL, pushed the project beyond simple translation. Layout, spacing, and component behavior had to stay coherent across multiple language contexts.
5. Using Solana in a way that felt honest
I did not want blockchain to feel forced.
Instead of making it the center of the product, I used Solana Devnet to write a symbolic memo tied to rescue badges. That kept it lightweight, real, and aligned with the product idea.
6. Handling iPhone image uploads for AI analysis
Another issue I ran into was image compatibility.
Photos taken on iPhones are often uploaded in HEIC, which is not always handled reliably by AI pipelines or downstream processing steps. Large image sizes were also increasing the chance of failed requests or unnecessary payload weight.
To solve this, I added a client-side preprocessing step before sending images to the AI:
- automatically convert HEIC images to JPEG
- resize and compress images to reduce file size
- reject oversized files with a clear user-facing error message if they still exceed the limit
This made the upload flow much more reliable and improved the overall experience, especially for mobile users.
What I learned
This project taught me that sustainability tools become much more interesting when they help with real decisions, not just awareness.
It also reinforced that AI is much more useful in production-like experiences when constrained into a structured output format.
And on the UX side, I learned that building a challenge project is not just about shipping features. It is also about making the project easy to understand and easy to review. The /demo route ended up being one of the most important decisions in the whole build.
How to run locally
1. Clone the repository
git clone https://github.com/brandon0405/Before-It-Becomes-Trash.git
cd Before-It-Becomes-Trash
2. Install dependencies
npm install
3. Create environment variables
Create a .env.local file with the required values:
APP_BASE_URL=http://localhost:3000
AUTH0_SECRET=your_auth0_secret
AUTH0_BASE_URL=http://localhost:3000
AUTH0_ISSUER_BASE_URL=https://your-auth0-domain
AUTH0_CLIENT_ID=your_auth0_client_id
AUTH0_CLIENT_SECRET=your_auth0_client_secret
AUTH0_AUDIENCE=
GEMINI_API_KEY=your_gemini_api_key
GEMINI_MODEL=gemini-1.5-flash
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
SQLITE_BACKUP_ENABLED=true
SQLITE_BACKUP_PATH=./.data/local-backup.db
SOLANA_NETWORK=devnet
SOLANA_PRIVATE_KEY_JSON=[1,2,3]
4. Run the development server
npm run dev
5. Open it locally
- Main app: http://localhost:3000
- Public demo: http://localhost:3000/demo
What I would improve next
If I keep building this project, the next things I would work on are:
- more material-aware recommendations
- better image-based classification
- location-aware recycling guidance
- richer explainability for recommendations
- stronger accessibility testing
- a deeper rescue scoring system
- community-contributed reuse ideas
- more meaningful onchain proof beyond symbolic memos
Prize Categories
I am submitting this project for:
- Best Use of Google Gemini
- Best Use of Solana
Gemini is used for structured, multilingual item analysis.
Solana Devnet is used to record symbolic badge memos tied to rescue actions.
Closing
For Earth Day, I did not want to build something that only talks about the planet in abstract terms.
I wanted to build something for the moment when a person is holding a real object and asking:
Should this be repaired, reused, recycled, or thrown away?
That is the space Before It Becomes Trash is trying to support.
If you try the demo, I would genuinely love feedback on the product and the implementation:
- Which object would you test first?
- Would you trust the recommendation?
- What would make the rescue decision feel more useful?
Thanks for reading.











Top comments (0)