DEEP RESEARCH: Supabase + OpenAI Natural Language Recommendation App: Design & Implementation Guide

DEEP RESEARCH: Supabase + OpenAI Natural Language Recommendation App: Design & Implementation Guide

April 14, 2025

Deep Research is a feature in ChatGPT (Pro, with GPT-4) that lets you ask real-time, web-connected questions and get up-to-date answers. It taps into the live internet to bring in fresh facts, breaking news, company info, or niche knowledge—anything that might not be baked into the model’s memory. Think of it like having a researcher who can scan the internet right now and summarize it for you in seconds.

Unlike standard responses, which rely on pre-trained knowledge, Deep Research checks what’s out there today—which is ideal when you’re working on current events, fast-changing topics, or obscure stuff.

This post was made using deep research. I am sharing it here as an example of how anyone can conceive of a project and create it using Deep Research. If you want to see my prompt, scroll to the bottom of the post.

Supabase + OpenAI Natural Language Recommendation App: Design & Implementation Guide

Introduction

Building a simple, elegant recommendation app involves orchestrating multiple services – from data APIs (for places and travel info) to AI for natural language output – all tied together with a clean UI and a Supabase backend. This guide provides a detailed walkthrough of the key components and best practices to create a minimalist app where users ask questions like “We need a last-minute place for a 2-year-old with squirrels and birds” and receive contextual suggestions (e.g. “Try Maple Park – it’s nearby and full of squirrels and birds!”) complete with photos and Google Maps links. We will cover the choice of APIs (for places, images, and travel data), obtaining API keys, structuring the Supabase database, prompting OpenAI for contextual responses, keeping the frontend ultra-minimal, managing codebases for local vs. travel versions, and monetizing through affiliate programs.

1. APIs for Data and Images

Google Maps Platform (Places API & Photos): For any location-based query (parks, attractions, etc.), the Google Places API is an excellent choice. It can interpret text queries or nearby searches to find relevant places (e.g. parks with playgrounds, nature reserves, etc.), and it provides rich details. Importantly, it supports Place Photos, giving access to millions of real photos of locations (Place Photos  |  Places API  |  Google for Developers). For example, a Place Details request can return photo references for a park, and you can fetch a photo via the Places Photo service (an HTTP URL) using that reference (Place Photos  |  Places API  |  Google for Developers) (android - How can I retrieve an image of a place from Google Places API? - Stack Overflow). This ensures the images in your app reflect actual places rather than generic stock photos. Google’s data will also provide names, addresses, coordinates, and potentially user ratings/reviews of places, which you can use to add context (e.g. distance from user, popularity). In addition, the Google Maps URLs service lets you create links that open the place in Google Maps (by using a Place ID in a maps.google.com URL) so users can get directions or more info (Get Started  |  Maps URLs  |  Google for Developers). Overall, Google’s API will cover most local recommendation needs (parks, restaurants, museums, etc.), and the images returned are real user-contributed photos of those places.

Travel and Affiliate Data APIs: For a travel-focused version (e.g. recommending hotels, unique stays, or attractions in a city), you’ll want to incorporate APIs that not only provide data and photos but also allow affiliate linking for monetization. Two primary candidates are:

  • Booking.com Affiliate API/feeds: Booking.com offers an affiliate program that gives developers access to its huge inventory of accommodations (over 28 million listings worldwide (Affiliate Program by Booking.com – earn money on your website)). Through their affiliate interface (accessible after joining their program), you can retrieve hotel details including photos, pricing info, etc., or at minimum obtain deeplinks to booking pages. Booking’s content includes property images and descriptions, and as an affiliate you’re allowed to use these to promote stays (with some terms). This means if a user’s query involves needing a place to stay (for example, in the travel planner app), you can search the Booking.com API for suitable hotels and display real photos of those hotels along with a link to book. The affiliate program then gives a commission on bookings made through your links (Affiliate Program by Booking.com – earn money on your website).
  • Travel Platforms for Attractions: If the travel version will suggest activities (museums, tours, etc.), look at APIs like Tripadvisor/Viator. Tripadvisor has an affiliate program allowing you to earn on hotel or tour bookings referred from your app (Tripadvisor Affiliate Program - Earn money on your website). They provide data on attractions and reviews, though their API access might be through partnership or networks like Travelpayouts. Viator (Tripadvisor’s tours marketplace) also offers affiliates data on local experiences (with images and descriptions of tours/activities). These can be used for a richer travel itinerary planner (e.g. recommending a cooking class in Paris with an image and booking link).

Comparative Overview: The table below summarizes the key APIs and their capabilities:

API/ServiceUse CaseReal Photos AvailableGoogle Maps LinksAffiliate MonetizationGoogle Places APILocal places (parks, cafes, etc.) search and details. Also used for geocoding user’s location context.Yes – via Place Photos (user-contributed images) ([Place Photos  Places API  Google for Developers](https://developers.google.com/maps/documentation/places/web-service/photos#:~:text=The%20Place%20Photo%20service%2C%20part,optimal%20size%20for%20your%20application)).Google Maps Static/Street View(Optional) Map thumbnails or street view imagery for context.Yes – static map or street view images.N/A (these are images).No.OpenAI API(Not for data retrieval, but for NL query understanding and generation.)N/AN/ANo (cost center, not revenue).Booking.com APIHotels/accommodations search for travel queries.Yes – property photos available to affiliates.Indirect – you’d link to Booking.com pages.Yes – commissions on bookings (Affiliate Program by Booking.com – earn money on your website).Tripadvisor APIAttractions, hotels, restaurants data + reviews.Yes – images via their content.Indirect – link to Tripadvisor site.Yes – e.g. ~8% commission on hotel bookings (Tripadvisor Affiliate Program - Earn money on your website) (Tripadvisor Affiliate Program - Earn money on your website).Airbnb (no public API)(Alternative accommodations – but no official public API for search data.)Yes – photos on site.Indirect – link to Airbnb.Affiliate program discontinued (Airbnb ended its Associates program in 2021 ([Airbnb Affiliate Program: What Are the Alternatives?

In practice, for the MVP local app, Google’s Places API is sufficient to cover queries about parks, child-friendly venues, etc., since it can interpret natural queries to some extent via text search, and you can filter or choose appropriate place types. For the travel planner, you might combine Google Places (for general points of interest in a city) with a hotel API (Booking.com) for lodging and maybe a tours API for activities, especially to enable future affiliate income.

2. Obtaining API Keys and Setting Up Integrations

Setting up the integrations involves getting API keys or credentials for each service and configuring your app to use them:

  • Google Cloud API Key (for Maps/Places): Sign up for a Google Cloud account if you haven’t already. In the Google Cloud Console, enable the Places API (and Maps JavaScript API if needed) under the Google Maps Platform. Create an API key credential. It’s best to restrict this key to your specific domain or environment (for example, restrict by HTTP referrer or IP address) for security. Note that Google’s APIs may require enabling billing (they have a free tier, but a billing account is needed to exceed it). Once you have the key, you’ll use it for any Places API HTTP requests (e.g. attaching &key=YOUR_API_KEY to the Place Details, Search, or Photo URL requests). Also obtain a Google Maps URL scheme for links – however, the Maps URLs don’t need a key, you just format the URL with the Place ID and query as documented (Get Started  |  Maps URLs  |  Google for Developers).
  • OpenAI API Key: Create an account on OpenAI’s platform (or log in if you have one) and generate a secret API key from the user dashboard. This key will be used on your backend (or serverless functions) to call OpenAI’s completions/Chat API. Keep it secret (do not expose it in frontend code). Typically, you’d store it in an environment variable on your server or Supabase Edge Functions. No complex setup beyond obtaining the key; just be aware of usage costs and model choices.
  • Supabase Project and Keys: If not done already, create a Supabase project. Supabase will provide a Project URL and an anon public key (for client-side use) as well as a secret service role key (for server privileged access). You’ll use Supabase’s client libraries with the URL and anon key in your frontend to read/write to the database (with Row Level Security policies as appropriate). Also enable Supabase Auth if you want user accounts (it provides a pre-built auth.users table and JWT auth out-of-the-box). No third-party key is needed for Supabase itself, just its provided credentials.
  • Booking.com Affiliate Setup: Joining Booking.com’s affiliate program is the first step. You can register through their Affiliate Partner Program page and will be directed to sign up via an affiliate network (Commission Junction (CJ) or Awin, depending on your region) (Affiliate Program by Booking.com – earn money on your website). Once approved, you’ll get an Affiliate ID. For simple integration, you might start by using affiliate deeplinks (special URLs that include your affiliate ID) to Booking.com search results or property pages – these are often the easiest way to monetize without a full API integration. If you want to use their APIs for data: Booking.com has a distribution API for partners, but access may require additional approval or use of their Affiliate Hub tools. Start simple: obtain your affiliate tracking ID and use their link building tool to create URLs to specific hotels or location searches that include your code. You can later incorporate the Booking.com API for searching hotels by city or keywords and retrieving JSON data of results (which would include hotel names, prices, and maybe a link to an image or a thumbnail). Be sure to read their guidelines on API usage and image usage – typically, affiliates are allowed to use images as long as they are used to promote Booking.com listings with proper links (and not stored long-term outside of that context) (Booking.com Affiliates: How do you (legally) get hotel photos? : r/Affiliatemarketing) (Booking.com Affiliates: How do you (legally) get hotel photos? : r/Affiliatemarketing).
  • Tripadvisor/Travel Affiliate APIs: For Tripadvisor, you’d join their affiliate program (which can be done via Travelpayouts or directly via Tripadvisor’s partner portal). After joining, you get an affiliate ID and access to tools to create links or widgets. Tripadvisor’s content (hotel ratings, attractions info) can often be accessed via their API or CSV feeds for partners. If using Travelpayouts (an affiliate network), you can get a single token that lets you access multiple travel affiliate APIs (they provide a unified system for searching hotels with Booking.com data, for example, or tours with Viator, all while handling the affiliate tracking). Setting this up might involve generating an API token on Travelpayouts and then calling their endpoints for e.g. hotel search. For the scope of this project, a full integration might be complex, so consider starting with straightforward affiliate links: e.g., if your travel app suggests “Paris hotels in Montmartre with great bistros nearby,” you could include a button “See hotels in Montmartre on Booking.com” with your affiliate link, rather than listing dozens of hotels within your app initially.

API Integration Tips: Once keys are obtained, integrate one service at a time. For example, first get Google Places working by writing a server-side function that, given a user query and/or location, calls the Places API (either a Text Search or Nearby Search for certain place types). Test that you can retrieve a few candidate places and a photo reference for each, then call the Photo API URL to get an image. After that, integrate OpenAI: feed it a prompt with the query and the place details to generate a friendly answer. Finally, incorporate affiliate links for any place that involves booking (maybe as part of the response or a separate link element). Keep keys in config files or environment variables and never commit them to Git. Supabase Edge Functions or your backend can act as a proxy to call external APIs if you need to keep keys hidden from the client (for instance, to fetch a Google Place Photo and return it to the frontend, so the Google API key isn’t exposed in the image URL).

3. Structuring the Supabase Database

Using Supabase (PostgreSQL) as the database, you’ll design a schema to store user queries, the AI’s results, and any user-related data. A logical, normalized structure will make it easy to track usage and even cache results for performance. Here’s a recommended structure:

  • Users: If you plan to have user accounts (so people can maybe save their favorite spots or view their query history), leverage Supabase Auth. Supabase’s auth.users table will automatically hold user info (UUID, email, etc.) after sign-up. You can create a profile table if you need to store additional info about users (e.g., preferences or home location). Each query will be linked to a user (or null if you allow anonymous usage).
  • Queries: A table to log each query made. Fields might include: id (PK), user_id (FK to users, nullable if anonymous), query_text (the exact natural language input), query_time (timestamp), and perhaps location (if the user’s current location or chosen location is stored, to help reproduce or analyze the query context). You might also store parsed_intent or category if you use OpenAI or logic to classify the query (e.g., “outdoor kid activity” as a category). Additionally, you could have a response_text field that stores the full text output given to the user (the narrative recommendation).
  • Results/Recommendations: If each query can yield multiple recommended places, you’ll need a table to store those individual recommendations. For example, recommendations table with fields: id (PK), query_id (FK to Queries), place_name, place_id (if from Google or Booking, to uniquely identify it), address or coordinates, image_url (link to the photo used), maps_url (the Google Maps link for this place), and maybe reason or ai_blurb (the sentence or two that the AI generated about why this place meets the query). Essentially, each entry here represents one place suggested for a given query. If you always return just one top suggestion, this table could be optional and you store that one result in the Queries table, but often you may return a small list (say 2-3 options), so a separate table is more flexible.
  • (Optional) Places Cache: You might create a places table as a cache for place details to avoid hitting the external API repeatedly for the same location. For example, if “Maple Park” is recommended often, cache its details (name, Google Place ID, etc.) and photo reference in your DB. You can update this if needed (maybe refresh every so often), but caching can speed up responses and reduce API calls. Use the Place ID or some external reference as a unique key in that table. Then recommendations could link to places table rather than storing duplicate info. This is an optimization to consider once things work end-to-end.

When designing these tables, ensure to define foreign key relationships (Supabase lets you do this via SQL or their GUI). For instance, queries.user_id references auth.users.id (or your profile table), and recommendations.query_id references queries.id. This maintains referential integrity. Supabase’s Postgres can also log automatically created timestamps (created_at) if you use their default timestamp with time zone and DEFAULT now() in table definitions.

Also consider adding an index on user_id in Queries if you plan to query a user’s history often, and on query_time if you might do analytics by date. Supabase can handle full-text search if you want to later search past queries or results, but that’s a stretch goal.

Example Schema:

TableKey FieldsDescriptionusers (auth)id (UUID, PK), email, etc.Managed by Supabase Auth (or use your own). Stores user identity.queriesid (PK), user_id (FK to users), query_text, query_time, response_textEach user query with the text and time. Optionally the AI’s answer text for record.recommendationsid (PK), query_id (FK to queries), place_name, place_id, image_url, maps_url, ai_blurbPlaces recommended for a query, with identifying info and the AI-generated blurb about each.places (cache)place_id (PK), name, address, photo_ref, last_updated(Optional) Cache of place details/photos to minimize external calls.

Using Supabase’s JavaScript or Dart client, you can easily insert a new query and associated recommendations in a transaction or sequential calls. Supabase also provides realtime if you ever want to show updates, but here it’s likely unnecessary. Ensure your Row Level Security policies (if enabled) allow the client to read their own queries and insert new ones (or disable RLS for these tables if you’re okay with open read access). Given this is mostly public recommendation data and not sensitive, you might not need strict RLS, though if users have accounts, you should partition their data by user_id with policies (so one user can’t read another’s history).

4. Contextual Natural Language Generation with OpenAI

One of the core features is using OpenAI to turn raw data into a friendly, contextual response. This involves prompting the model effectively with the user’s query and the information you retrieved from APIs. Here are best practices for achieving high-quality natural language output:

  • Understanding the Query Intent: User queries are in natural language and might be vague or complex (“last-minute place for a 2-year-old with squirrels and birds” carries a lot of implied intent). Use OpenAI to parse or classify the query if needed. For instance, you could have an initial prompt like: “The user query is: 'We need a last-minute place for a 2-year-old with squirrels and birds.' Identify what the user is looking for in terms of location type and key features.” The model might answer with something like: “They want a nearby outdoor place (likely a park) that has wildlife (squirrels, birds) and is suitable for a toddler.” This step isn’t strictly necessary, but it can help you programmatically decide which API to call (park search vs. something else). Alternatively, you can infer heuristically (mention of squirrels/birds -> park or zoo). The power of GPT models is that they can capture nuance that traditional keyword search might miss – “There’s no filter for heart-shaped beds or Elvis impersonators,” as one travel product director noted, referring to how quirky intents need AI interpretation (Personalizing travel at scale with OpenAI | OpenAI). GPT can handle those nuances, allowing a more conversational and intent-driven experience than hard filters (Personalizing travel at scale with OpenAI | OpenAI).
  • Retrieving Relevant Data: Once you have an idea of what the user wants, query the appropriate API. For our example, you’d use the Google Places API (perhaps a Nearby Search around the user’s location for type=park or a Text Search with keywords “park squirrels birds near {city}”). Suppose this returns a list of candidate places (e.g., Maple Park, Oak Zoo, Riverside Playground) each with some details (ratings, distance, maybe snippets of reviews). It’s often a good idea to pick the top results based on a combination of relevance and quality – for example, you might take the top 3 highest-rated matches that fit the criteria. Rather than giving the AI everything, you can already filter to the best options. (One approach is highlighted by Ural (2025) where raw API results are refined to “highlight the top 3 best-rated locations” instead of dumping everything (Spring AI + Location: Create a Hyper-Personalized Chatbot in Minutes!).) This aligns with giving the user a concise, quality result.
  • Composing the Prompt for OpenAI: Now, prepare a prompt that gives the model the context it needs to generate a helpful response. A suggested structure for the prompt:
    • A brief system or instruction message, e.g.: “You are an assistant that suggests local places in a friendly tone. Provide a recommendation based on the data provided, explaining why it fits the request, and include the place name.”
    • The user’s query (or a summary of the need).
    • The data about the places you found. For example, you could feed a short description of each candidate: “1. Maple Park – 1.2 miles away, a quiet park with lots of trees (Rated 4.6★). 2. Riverside City Zoo – 3 miles away, small zoo with local animals (Rated 4.4★). 3. Oak Playground – 0.5 miles away, playground area with some trees (Rated 4.0★).” You might also include any specific matching info (e.g., “Maple Park: visitors often feed squirrels.” If you have a Google review snippet mentioning squirrels, that’d be gold to include).
    • Finally, instruct the model: “Recommend the best option to the user in a single paragraph, mentioning how it has squirrels/birds and is good for a 2-year-old, and sound confident.”
    By providing structured data to the AI, you ground its response in reality and reduce hallucinations. The model will use the details to form a sentence like: “Maple Park might be the perfect choice – it’s a quiet nearby park (about 1 mile away) with plenty of trees that attract squirrels and birds, so your 2-year-old can enjoy watching them. It’s a relaxing spot that families love, and it’s easy to get to last-minute.” The mention of distance, animals, etc., come from the data we supplied. This approach is called retrieval-augmented generation (you retrieve facts first, then let the model write based on them). It ensures the answer is contextual and accurate.
  • Model Selection and Tone: Use GPT-4 if possible for the best understanding of nuanced queries and more coherent, creative responses. GPT-3.5 (Turbo) can also work and is cheaper/faster, but you may need to experiment with prompts to get the desired quality. In either case, clearly specify the desired style in the prompt (e.g., “respond in a friendly, conversational tone, in the third person” or however you want it). For a very “natural” output, you can allow a bit of personality, but since this is an app response, it should stay professional and helpful.
  • Multiple Recommendations vs Single: Decide if you want the AI to present one recommendation or a few options. A minimalist approach might just give one best suggestion in natural language and perhaps list a couple of alternatives as shorter mentions. You can prompt the model accordingly. For example, you might say “If appropriate, mention a second option briefly.” Keep the output concise so as not to overwhelm the user – a short paragraph or a few bullet points at most.
  • Preventing Misinformation: Because the AI might try to be too clever, ensure it doesn’t fabricate details. In the prompt, you can say “Use only the information provided. Do not make up any facts not given.” If a user query asks something beyond what your data covers (e.g., “Is it open now?” or “Does it cost money?”), you either handle that separately or instruct the AI to respond that availability/cost is not in this scope. Since the requirement explicitly says real-time availability isn’t needed, the AI can omit those details or answer in general terms (“It should be open during normal park hours”). Testing different queries will help refine your prompts to handle edge cases.
  • Function Calling (Advanced): OpenAI’s newer feature of function calling could be used so that the model itself suggests when to call the Places API (essentially turning the flow around – the model given the query might output a function call like search_parks(location="X", keyword="squirrels") which your code executes, then you feed results back, etc.). This can simplify the logic and make the conversation iterative. However, for a first version, a more straightforward pipeline (parse -> search -> then generate) is easier to implement and debug. Best practice is to keep the roles clear: your code handles data retrieval and leaves the AI to do the language part, not the logic part.
  • Privacy and Rate Limits: Each call to OpenAI and Google costs money or has quotas – caching results in the database (as discussed) and perhaps caching the AI output for identical queries can help. Also, consider using moderate temperature (0.7 or so) for creativity but not too high to avoid randomness. Monitor the content of AI outputs, especially if you allow any user query – use OpenAI’s content filter or review the outputs to ensure it doesn’t say something inappropriate or incorrect about a real place. Keep the tone positive and helpful.

By following these practices, you harness OpenAI to produce responses that feel human and contextual (“this park is close and has squirrels”) rather than a dull list of places. The goal is a concierge-like feel: the app understands what the user really wants and responds helpfully as if a local friend made a suggestion.

5. Frontend Design: Keeping it Ultra-Minimal

For the user interface, the mantra should be “less is more.” A minimalist UI will put the focus on the query input and the recommendations, avoiding any clutter that could distract or confuse users. Here are guidelines to achieve the white-on-white, simple aesthetic described:

  • Color Scheme and Layout: Embrace whitespace. Use a white background for the majority of the app, and if needed, a very light gray (#f9f9f9, for example) for card backgrounds to slightly stand out against pure white. Subtle contrast can be achieved by shadows or borders rather than colors. Rounded corners on containers (e.g., a search box or result card) make the design feel modern and friendly (rounded corners are perceived as more approachable (Why rounded corners are everywhere? : r/UI_Design - Reddit)). Keep the corner radius modest (maybe 5px to 8px) for a subtle effect. Ensure there’s ample padding around text and elements so the interface feels airy and not cramped.
  • Typography: Use a clean, legible font with minimal styles. A single typeface (like a sans-serif such as Inter, Roboto, or Helvetica Neue) with maybe two weights (regular for body text, medium or semi-bold for headings) is sufficient. Black or dark gray text on white is highest for readability. Avoid text shadows or extravagant effects. The query input can be slightly larger font to invite interaction. Any result titles (place names) might be a bit bold or larger, with the descriptive text below in normal weight.
  • Layout Simplicity: The app can essentially be one primary screen: at the top, a prompt like “What are you looking for?” and a single-line text input (with a search icon perhaps). When the user submits a query, show the results below. Each result could be in a card: perhaps an image on one side or on top, and text on the other side or below. Since the requirement is natural language recommendations with photos, a common design is to have a medium-size photo with a short text overlay or caption. For example, you could show the photo of the recommended place as a banner, and overlay the place name and distance in a corner of the image (in white text with a slight shadow for contrast). Beneath the image, show the AI’s sentence in a simple text block. Beneath that, perhaps two action buttons/links: one for “Open in Google Maps” (with a map pin icon) and maybe another if needed (like “More options” if you plan to show multiple suggestions or “Book now” if it’s a hotel with an affiliate link). However, even buttons can be just text links to keep it simple, or small icon buttons.
  • Minimalism Best Practices: Every element on the screen should serve a purpose. If something can be removed without hurting usability, remove it. Use of whitespace and typography as the primary design elements means the user’s eye will naturally go to the content. Clutter is the enemy – as design articles note, a clean design helps users process information easily (17 Minimalist UI Inspirations that Prove Less is More - Unlimited Graphic Design Service). So if you have multiple results, stack them in a straightforward vertical list. Number them only if necessary. Avoid sidebars, complex menus, or extraneous images/graphics. A small logo or app name at the top is fine, but keep it discreet. Animations should be minimal or absent; perhaps a simple loading spinner or skeleton screen while fetching data is all you need.
  • Responsive and Mobile-Friendly: Given many users will likely be on mobile when looking for “last-minute” places, ensure the design scales to smaller screens. A single-column layout works well on mobile (one result card per row). Use relative units or flexbox/grid to make the image and text wrap nicely. The white minimalist design inherently tends to be mobile-friendly because it’s not pixel-perfect dependent on large screens.
  • Example UI Elements: The search input might be just a bordered input with a slight shadow or border-radius, centered on the page. The result card might look like a Polaroid: picture on top, caption below. Or for a more text-focused approach, you might place the image as a thumbnail to the left of a text paragraph. Try a few variations and see which feels cleanest. Maintain consistency: all images could be the same size or aspect ratio for uniformity (Google Place Photos can be requested at a fixed max width for consistency). If an image is not available, have a neutral placeholder (like a gray box or an outline of a camera) rather than breaking the layout.
  • Inspiration: Think of Google’s own interfaces (Google’s homepage is the epitome of minimalism – just a logo and a search bar). Also many modern apps use neumorphism or flat design principles to stay minimal: e.g., white cards on white background with subtle drop shadows to distinguish sections. You can also leverage a minimalist CSS framework or component library to speed up development – for example, Tailwind CSS is great for quickly styling with utility classes (and you can define a minimal color palette easily), or something like Chakra UI or Ant Design can be used but you’d need to strip down their styles to achieve truly minimal look. It might be simplest to handcraft a few CSS styles for this small app.

Remember, a minimalist UI not only looks elegant but also helps users focus on the content (their question and your answer) without distraction. It tends to improve usability by reducing cognitive load (17 Minimalist UI Inspirations that Prove Less is More - Unlimited Graphic Design Service). So stick to the basics: a calming white interface, clear text, and the occasional image to enrich the recommendations.

6. Codebase Structure: One Shared Base or Separate Apps?

Since you envision both a local recommendations app and a broader travel planner app (which share the same core logic but serve slightly different purposes), you need to decide whether to keep them in one codebase or split them. Both approaches have pros and cons:

  • Single Codebase (Monorepo or Single App with Modes): Keeping everything together can simplify development if there is a high degree of overlap in functionality. You could architect the app to have a toggle or mode for “local” vs “travel.” For instance, the backend logic to handle a query could detect if it’s a travel-type query (e.g. mentions of flights, remote places, multi-day trip) and route to travel data sources, otherwise use local data. In a single repository, you can also share components easily: the UI components, the OpenAI prompting functions, the database, etc., can be reused. A monorepo with two frontends (say two Next.js apps or two React projects) and a shared library for common code is one way – changes to core logic instantly apply to both, which is convenient. If you deploy them as separate services (different URLs/domains), they can still pull from the shared code. The downside is complexity in code: you’ll constantly need to handle conditional differences (the travel planner might need more data fields, or a different presentation for multi-day itinerary). Over time, the two apps might diverge in requirements, making a single codebase harder to maintain (lots of if/else or config flags to handle differences).
  • Separate Codebases: This means essentially treating them as distinct projects. You might still share some code by copying modules or using a private package that both can import, but they are managed independently. The advantage is clarity of purpose – each codebase is simpler because it caters to one context. The local app can remain very lightweight, while the travel app might grow in complexity (e.g., adding user trip planning features, saving itineraries, etc.) without affecting the local app. Also, if you have different branding or domain for the travel site, a separate codebase aligns with separate deployment. The downside is potential duplication of code – if the logic for query parsing, AI prompting, etc., is the same, you’d have to update it in two places or make a shared library. One way to mitigate duplication while still separating projects is to factor out the common logic into a small library (could be a npm package or a Git submodule) that both projects use. For example, a module that contains “findRecommendations(query, location)” which calls the APIs and returns the AI answer. Both the local and travel app could call this function. You’d maintain that module separately.

Given that the travel planner is described as “a separate app/website using the same logic,” it sounds like you indeed will have two user-facing products. A reasonable approach is to build the local app first (simpler scope) and abstract its core logic in a way that can be reused. Then, create the travel app and import that logic. If you are using a framework like Next.js, you could even set up a monorepo with two Next.js apps and shared utility files. Or if using plain JS/TS, have two frontends that both call the same backend service (you could even create a single backend API, say in Supabase Edge Functions or a Node server, that both UIs talk to). For example, a single /recommend endpoint could handle both kinds of queries by checking a flag or content, and the two frontends are mostly UI variations.

Recommendation: Start with a shared backend logic and separate frontends. The local app UI will be tailored to quick one-off queries, whereas the travel planner UI might allow more input (date of travel, multi-step conversation for planning an itinerary, etc.). Keeping those UIs separate will make the user experience more focused for each use-case. But they can still call the same backend functions or microservices behind the scenes. This way, improvements to the core recommendation engine benefit both apps, but neither frontend bloats the other. In Git terms, you could do a monorepo (one repository containing e.g. apps/local-app, apps/travel-app, and libs/core) to organize this. Many companies use monorepos to manage multiple apps with shared code (Creating a monorepo for the various web apps we may have). Just be sure to clearly separate any differing configurations (for example, the travel app might use additional API keys like a flights API, which the local app doesn’t need).

If the two apps will be maintained by one small team, a shared codebase (monorepo) is fine. If you foresee possibly open-sourcing one or having different teams, you might lean separate. But given the overlap (“same logic”), you should not rewrite the logic twice. Reusing through modular design or libraries will save time.

7. Monetization via Affiliate Programs

To turn this app (especially the travel version) into a revenue-generating product, affiliate programs are the primary avenue. The idea is to earn a commission when users, inspired by your AI’s recommendation, click through and make a booking or purchase. Here are some monetization strategies and programs, focusing on ease of implementation for a startup project:

  • Booking.com Affiliate Partner Program: Likely the easiest and most lucrative starting point for accommodations. After joining (as described above), you can generate tracked links. For example, if your app recommends a specific hotel or even just “hotels in X area”, you can embed a link such as “View on Booking.com” that contains your affiliate ID. Booking.com pays a percentage commission on completed stays that came through your referral (the exact percentage can vary, but expect on the order of a few percent of the booking value). The program is known for being straightforward: “Add links, banners, and other tools to your site… Earn a commission on qualified bookings made through your integrations” (Affiliate Program by Booking.com – earn money on your website). They also offer API access so you can search hotels and display some info directly in your app (which could improve user experience by not always sending them off-site immediately), but implementing that means handling more data (listing hotels, updating prices, etc.). To start simple, a deep link is enough. For example, your AI might recommend “Grand Hotel in Paris”, so you make the hotel name clickable, linking to the Booking.com page for Grand Hotel with your affiliate tag. If the user books, you get credit. Ease: Very high (just use provided link structure). Note: Do not forget to comply with any display guidelines—some programs require you to show a disclaimer that links are affiliate, etc., especially if the app is publicly distributed.
  • Tripadvisor Affiliate Program: Tripadvisor’s program (which can be joined via Travelpayouts or CJ) can complement Booking.com. Tripadvisor is a bit unique: it can pay for hotel bookings (often the booking is actually fulfilled by a partner like Booking or Expedia, but you get paid via Tripadvisor for sending the user), and also for things like tour and activity bookings (through Viator). Commission rates can be attractive (Travelpayouts notes ~8% on bookings (Tripadvisor Affiliate Program - Earn money on your website) for hotels via Tripadvisor, and possibly 6-10% on tours via Viator). The easiest integration here is to use deep links or widgets from Tripadvisor. For example, if your travel app says “Consider a Seine River Cruise in Paris,” you could link that text to a Viator listing for a specific cruise with your affiliate code. Tripadvisor provides a portal where you can search for destinations or specific tours and get a ready-made link. Ease: Moderate (Tripadvisor’s affiliate is slightly more involved to get set up, but not too hard). If you sign up through Travelpayouts, you get access to a dashboard to create links easily.
  • Expedia Group Affiliate (EAN/TAAP): Expedia has an affiliate network as well (Expedia Affiliate Network and Travel Agents Affiliate Program). Through EAN, you can access data for hotels, flights, car rentals, etc., and earn commissions. However, Expedia’s program might require a more formal approval and is somewhat geared towards travel agencies and larger partners. It might not be as immediate to get started as Booking.com’s. If Booking inventory covers your needs (which it often does for hotels), you might skip Expedia initially. That said, Expedia’s program could allow monetizing things like flights or packages if your travel app expands in that direction. Ease: Low (requires more development to integrate their XML/JSON APIs and possibly more hurdles to join).
  • Airbnb Referral Program: As noted, Airbnb shut down their public affiliate program in 2021 (Airbnb Affiliate Program: What Are the Alternatives? | Hospitable). They currently focus on a host referral program (rewarding people who bring new hosts). So, for earning via recommending stays, Airbnb is unfortunately not an option at the moment. Stick to Booking.com or even Agoda (Agoda is a sister company of Booking and also has an affiliate program, particularly strong in Asia, that could be joined via the same networks).
  • Tours & Activities (Viator, GetYourGuide): If your travel planner will recommend experiences (museums, tours, events), consider affiliate links to booking platforms for those. Viator (owned by Tripadvisor) has an affiliate program (one can join via CJ or directly) that pays for tour bookings. GetYourGuide is another tours booking site with an affiliate program (and API). These typically offer around 8-10% commission on activities. Implementing them could be as simple as linking to a specific activity page. For example, “Eiffel Tower Skip-the-Line Ticket” could be a link. If you want to dynamically pull tours, their APIs can search by city or attraction.
  • Google AdSense or Banner Ads (Alternative): If for some reason affiliate integration is slow or you want additional revenue, you could consider placing a minimal banner ad or using AdSense in the interface. However, given the minimalist ethos of the app, banner ads might detract from the user experience significantly. They also wouldn’t be very contextual (AdSense might show random ads not directly tied to the query). Therefore, affiliate links which are naturally part of the recommendations (e.g., a “Book this hotel” button) are preferable: they integrate with the user flow rather than distract from it.
  • Monetizing Local Queries: The local recommendations (e.g., parks, free activities) won’t directly make money via affiliate links because you can’t exactly get commission on “visiting a park”. But what you can do is use the travel version for cases where monetization is possible (hotels, attractions). In the future, if the local app gains a user base, you could strike deals with local businesses (e.g., partner with a kid-friendly cafe to recommend it and get a referral fee), but that’s a business development effort outside the scope of straightforward affiliate programs. In the meantime, focus on travel and accommodations for revenue.

Easiest Programs to Start: In summary, Booking.com’s affiliate is the easiest and most immediately beneficial for accommodations – it’s free to join, easy to implement (just a link with a code), and covers a huge range of inventory (Affiliate Program by Booking.com – earn money on your website). Tripadvisor/Viator would be next to consider, giving you coverage of hotels (additional) and activities, with relatively easy link tools. GetYourGuide is also fairly easy (they have a self-serve affiliate signup as well). These programs don’t require up-front costs – you only gain revenue when users book something, so it’s a performance-based model.

Make sure to place affiliate links in a way that feels natural and not spammy. For example, a travel itinerary result could say: “You might stay at Sea Breeze Hotel – a top-rated beachfront hotel. [Book now](https://…affiliate link…) or see it on the map.” The “Book now” would carry your affiliate URL. Always test your links to ensure the tracking is working (the affiliate dashboard should show clicks and bookings).

Finally, as you integrate these, do check the terms of service. Some programs (like Booking.com) allow using their brand name and content in certain ways but might require attribution or have rules about not storing data long-term. Google Places has usage limits and terms (usually requiring attribution if maps data is used publicly). It’s good practice to attribute data sources where needed (e.g., you might include a small text like “Powered by Google” logo if using Google data heavily, and mention “Booking.com” in context of hotel links to be transparent).

By starting with affiliates that are easiest and most relevant to your content, you set up a path to monetize the app’s advice while keeping the user experience seamless – the user asks a question, gets a helpful answer, and if that answer involves a booking, they can follow through conveniently with a couple of taps, earning you a commission in the process.

Conclusion

With the right combination of technologies, you can deliver a delightful experience: users ask in plain English for a specific need, and your app intelligently interprets it, finds matching places through APIs, and responds in a human-like way complete with visuals and map links. Supabase provides the glue (database and potential serverless functions) to store data and handle user management, OpenAI adds the magic of understanding and natural language generation, and external APIs like Google Places and Booking.com supply the real-world data and images. The design remains clean and minimalist so that the content shines. By structuring the project carefully and leveraging affiliate programs, the app can even generate revenue as it scales.

In essence, you’re building a smart concierge that lives on the web – one that can suggest a toddler-friendly park today and plan a Paris vacation tomorrow, all through the power of data and AI working in harmony. Good luck with your implementation, and happy coding!

Sources:

  1. Google Maps Places API – Place Photos documentation (Google Developers) (Place Photos  |  Places API  |  Google for Developers)
  2. Google Maps URLs – Using place IDs to create map links (Google Developers) (Get Started  |  Maps URLs  |  Google for Developers)
  3. OpenAI on conversational intent in travel planning – Booking.com case study (Personalizing travel at scale with OpenAI | OpenAI)
  4. Ural, H. (2025) – Location-Based Chatbot (on refining API results with AI) (Spring AI + Location: Create a Hyper-Personalized Chatbot in Minutes!)
  5. Pascual, K. – Minimalist UI Design Principles (Penji.co) (17 Minimalist UI Inspirations that Prove Less is More - Unlimited Graphic Design Service)
  6. Booking.com Affiliate Program info – commission on bookings (Affiliate Program by Booking.com – earn money on your website) (Affiliate Program by Booking.com – earn money on your website)
  7. Hospitable.com – Airbnb affiliate program ending in 2021 (Airbnb Affiliate Program: What Are the Alternatives? | Hospitable)
  8. Travelpayouts – Tripadvisor Affiliate overview (commission rate) (Tripadvisor Affiliate Program - Earn money on your website)

The original ChatGPT Deep Research Prompt:

Hi there! I’d like to use lovable to create an app that you can search for anything you want using natural language and it gives you a list of recommendations. For example, we got to a museum and it was sold out, so we needed to find another place to bring a 2 year old real fast. Ideally with squirrels and birds. I’d like to be able to put that in a search box and it deliver results in natural language with photos and links to Google maps.I want it to be VERY simple in design. Think white on white with soft but not lots of curve on the corners.I am using supabase.Please also walk me through what I need to get in terms of api keys and what answers I need to give.