# Google Authentication in Python and Flask Source: https://docs.replit.com/additional-resources/google-auth-in-flask Learn how to implement Google OAuth authentication in a Flask app on Replit, including user login and Google Sheets API integration. Allowing your users to log in to your website using their Google account has these benefits: 1. You don't have to implement your own authentication scheme. 2. You can get users' name and contact information easily. 3. You can use the same credentials to access users' Google resources like Sheets and Drive. This guide that will walk you through how to do that with Python and Flask on Replit. First, we'll walk through how to setup basic OAuth authentication, then cover how to use the resulting credentials to access users' Google resources. ## Introduction to OAuth Google authentication is based on the OAuth standard. The way OAuth works is as follows: 1. Somewhere on your website, you direct a user to a login page. 2. When they go to the login page, you don't implement the login form on your website, but instead redirect to Google's login service to login the user. 3. When Google's login service successfully logs in the user, it redirects back to your website at a predefined URL of your choosing, say `https://YOUR_DOMAIN/oauth2callback`, while sending some information pertinent to the user and the login session. 4. You use the user's login information to further obtain an access token, which is like a pass you can use to access the user's resources, like their profile information, their spreadsheets, documents and more. ## OAuth: Show me the code If you are like me, the first thing you want is working code. The code below is what you need. However, you'll need to set up some things in your Google Cloud Console in order to get everything working. That will be covered in the next section. Create a new Replit App using the [Flask template](https://replit.com/@replit/Flask?v=1) and put the following in `main.py`. The comments in the code explains what the individual parts do: ```python theme={null} from flask import Flask, redirect, session, url_for, request import google_auth_oauthlib.flow import json import os import requests app = Flask('app') # `FLASK_SECRET_KEY` is used by sessions. You should create a random string # and store it as secret. app.secret_key = os.environ.get('FLASK_SECRET_KEY') or os.urandom(24) # `GOOGLE_APIS_OAUTH_SECRET` contains the contents of a JSON file to be downloaded # from the Google Cloud Credentials panel. See next section. oauth_config = json.loads(os.environ['GOOGLE_OAUTH_SECRETS']) # This sets up a configuration for the OAuth flow oauth_flow = google_auth_oauthlib.flow.Flow.from_client_config( oauth_config, # scopes define what APIs you want to access on behave of the user once authenticated scopes=[ "https://www.googleapis.com/auth/userinfo.email", "openid", "https://www.googleapis.com/auth/userinfo.profile", ] ) # This is entrypoint of the login page. It will redirect to the Google login service located at the # `authorization_url`. The `redirect_uri` is actually the URI which the Google login service will use to # redirect back to this app. @app.route('/signin') def signin(): # We rewrite the URL from http to https because inside the Replit App http is used, # but externally it's accessed via https, and the redirect_uri has to match that oauth_flow.redirect_uri = url_for('oauth2callback', _external=True).replace('http://', 'https://') authorization_url, state = oauth_flow.authorization_url() session['state'] = state return redirect(authorization_url) # This is the endpoint that Google login service redirects back to. It must be added to the "Authorized redirect URIs" # in the API credentials panel within Google Cloud. It will call a Google endpoint to request # an access token and store it in the user session. After this, the access token can be used to access # APIs on behalf of the user. @app.route('/oauth2callback') def oauth2callback(): if not session['state'] == request.args['state']: return 'Invalid state parameter', 400 oauth_flow.fetch_token(authorization_response=request.url.replace('http:', 'https:')) session['access_token'] = oauth_flow.credentials.token return redirect("/") # This is the home page of the app. It directs the user to log in if they are not already. # It shows the user info's information if they already are. @app.route('/') def welcome(): if "access_token" in session: user_info = get_user_info(session["access_token"]) if user_info: return f""" Hello {user_info["given_name"]}!
Your email address is {user_info["email"]}
Log out """ return """

Hello!

Sign In via Google
""" # Call the userinfo API to get the user's information with a valid access token. # This is the first example of using the access token to access an API on the user's behalf. def get_user_info(access_token): response = requests.get("https://www.googleapis.com/oauth2/v3/userinfo", headers={ "Authorization": f"Bearer {access_token}" }) if response.status_code == 200: user_info = response.json() return user_info else: print(f"Failed to fetch user info: {response.status_code} {response.text}") return None @app.route('/logout') def logout(): session.clear() return redirect('/') if __name__ == '__main__': app.run(host='0.0.0.0', port=5000) ``` ## Set up your OAuth App / Client To get the above code working, you'll need to do these things in Google Cloud. 1. Create a Google Cloud project (if you don't already have one). 2. Configure the OAuth consent screen. 3. Create an OAuth client ID for your app. ### Create a Google Cloud project If you already have a Google Cloud project you want to use for this exercise, you can skip this step. 1. Go to the [Google Cloud Console](https://console.cloud.google.com/) 2. Click on the project selector dropbox next to the Google Cloud logo: Google Project Dropdown 3. Select an existing project or Click "New Project" and create an new project. Select Project 4. If creating a new project, enter a project name, and click "Create". New Project If you see your new project show up in a popup, click "Select project" to make that the *active project*. ### Configure the OAuth consent screen Now that you have a project, you can configure the OAuth consent screen for it: 1. Go to the [OAuth Consent Screen](https://console.cloud.google.com/apis/credentials/consent) OAuth Consent Screen 2. Make sure the project in the project drop down is the one you want. 3. Select "External" to allow any user to log in to your app with a Google account. "Internal" will allow only people from your organization. 4. Click "Create". 5. Enter an app name and the email of the person supporting this app (you?) OAuth Consent Screen 6. Enter an email address under "Developer contact information". Developer contact information 7. Click "Save and continue". 8. In the Scopes screen, you can add the APIs you want your app to have access to. You already have access to the APIs for getting basic user information. OAuth Scopes For now, leave this as is and click "Save and continue". 9\. In Test Users, you need to add the email of the users you want to be able to test the app during its testing phase. Test Users Click "Add users" 10\. Add one or more email Google email addresses, and click "Add". Test Users Then click "Save and continue". 11\. Review the summary screen. You can always go back and edit any of the steps. Test Users ### Create an OAuth client ID for your app This is the last part. To get OAuth working, you need to create an OAuth client ID for the app. 1. Go to [Credentials](https://console.cloud.google.com/apis/credentials). Test Users 2. Click "Create credentials" Test Users select "OAuth client ID". 3\. Select "Web application" for Application type. Enter a name for this client ID. Test Users 4. Now, go to your Flask Replit App. Open the shell, and enter: `echo https://$REPLIT_DEV_DOMAIN/oauth2callback`. The result will look something like: `https://81309e9b-c4df-48e0-a2c2-0a8d3c0e3162-00-35ppsa0tcuv6v.infra-staging.replit.dev/oauth2callback`. Copy this text and enter it as one of the "Authorized redirect URIs" in the bottom of the form Test Users Later when you publish your app, you'll want to come back here to add another entry `https://YOUR_APP_DOMAIN/oauth2callback` 5. Click "Create" 6. Click "Download JSON": Test Users 7. Go to your Replit App again, open the Secrets pane. Create a secret named `GOOGLE_OAUTH_SECRETS`, and paste of the contents of the downloaded file as the secret value. Test Users Phew! That was tedious. Congratulations if you made it through! Now you can run the Flask app and log in using a test user Google account. To make your app available to any Google user, you'll need to go back to the [consent page](https://console.cloud.google.com/apis/credentials/consent) and click "Publish App". A verification process may be required if your app requires additional Google APIs like Sheets and Drive. Next, we'll cover how to integrate with a Google API like Sheets. Follow along if you want to go further. ## Google Sheets API Setup In order to add a Google API integration like Google Sheets, first you need to enable the API for the app. You can [browser the available APIs](https://console.cloud.google.com/apis/library). As an example, we'll use Google Sheets. 1. Go to the [Google Sheets API listing page](https://console.cloud.google.com/apis/library/sheets.googleapis.com). 2. Click "Enable". Done! That's all the Google Cloud setup you had to do for this part. ## Google Sheets Integration: Show me the code First, in the oauth flow section of the original code, we leave everything the same, except add `"https://www.googleapis.com/auth/spreadsheets.readonly"` to the list of scopes: ```python theme={null} # This sets up a configuration for the OAuth flow oauth_flow = google_auth_oauthlib.flow.Flow.from_client_config( oauth_config, # scopes define what APIs you want to access on behave of the user once authenticated scopes=[ "https://www.googleapis.com/auth/userinfo.email", "openid", "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/spreadsheets.readonly" ] ) ``` Now, the way you access a Google API with the `googleapiclient.discovery` library is to first create a `Credentials` object using the access token, and then use the `build` function to create a callable API object. For the sheets API it looks like: ```python theme={null} credentials = google.oauth2.credentials.Credentials(token=session['access_token']) service = build("sheets", "v4", credentials=credentials) sheets_api = service.spreadsheets() ``` As to how to actually use the Sheets API, I've created a couple of helper functions: ```python theme={null} # fetch all sheets within a Google spreadsheet def get_sheets(sheets_api, spreadsheet_id) -> list[str]: result = sheets_api.get(spreadsheetId=spreadsheet_id).execute() return [sheet["properties"]["title"] for sheet in result["sheets"]] # fetch the data for a given sheet within a Google spreadsheet def get_sheet_data(sheets_api, spreadsheet_id, sheet_title) -> list[list[str]]: result = ( sheets_api.values() .get(spreadsheetId=spreadsheet_id, range=sheet_title) .execute() ) return result["values"] ``` With the above help, we can create a POST handler endpoint that imports a Google spreadsheet like so: ```python theme={null} @app.route("/import_spreadsheet", methods = ['POST']) def import_spreadsheet(): if 'access_token' not in session: return redirect('/signin') spreadsheet_id = request.form["spreadsheet_id"] credentials = google.oauth2.credentials.Credentials(token=session['access_token']) service = build("sheets", "v4", credentials=credentials) sheets_api = service.spreadsheets() try: sheets = get_sheets(sheets_api, spreadsheet_id) data_by_sheets = {} for sheet in sheets: data = get_sheet_data(sheets_api, spreadsheet_id, sheet) data_by_sheets[sheet] = data except googleapiclient.errors.HttpError as e: return f"upload failure" dirpath = os.path.join("static", "uploads", spreadsheet_id) filepath = os.path.join(dirpath, "data.json") os.makedirs(dirpath, exist_ok=True) with open(filepath, "w") as file: json.dump(data_by_sheets, file) return "upload success!" ``` Here is the full working code: ```python theme={null} from flask import Flask, redirect, session, url_for, request import google_auth_oauthlib.flow import json import os import requests from googleapiclient.discovery import build import googleapiclient.errors import google.oauth2.credentials app = Flask('app') # `FLASK_SECRET_KEY` is used by sessions. You should create a random string # and store it as secret. app.secret_key = os.environ.get('FLASK_SECRET_KEY') or os.urandom(24) # `GOOGLE_APIS_OAUTH_SECRET` contains the contents of a JSON file to be downloaded # from the Google Cloud Credentials panel. See next section. oauth_config = json.loads(os.environ['GOOGLE_OAUTH_SECRETS']) # This sets up a configuration for the OAuth flow oauth_flow = google_auth_oauthlib.flow.Flow.from_client_config( oauth_config, # scopes define what APIs you want to access on behave of the user once authenticated scopes=[ "https://www.googleapis.com/auth/userinfo.email", "openid", "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/spreadsheets.readonly" ] ) # This is entrypoint of the login page. It will redirect to the Google login service located at the # `authorization_url`. The `redirect_uri` is actually the URI which the Google login service will use to # redirect back to this app. @app.route('/signin') def signin(): # We rewrite the URL from http to https because inside the Replit App http is used, # but externally it's accessed via https, and the redirect_uri has to match that oauth_flow.redirect_uri = url_for('oauth2callback', _external=True).replace('http://', 'https://') authorization_url, state = oauth_flow.authorization_url() session['state'] = state return redirect(authorization_url) # This is the endpoint that Google login service redirects back to. It must be added to the "Authorized redirect URIs" # in the API credentials panel within Google Cloud. It will call a Google endpoint to request # an access token and store it in the user session. After this, the access token can be used to access # APIs on behalf of the user. @app.route('/oauth2callback') def oauth2callback(): if not session['state'] == request.args['state']: return 'Invalid state parameter', 400 oauth_flow.fetch_token(authorization_response=request.url.replace('http:', 'https:')) session['access_token'] = oauth_flow.credentials.token return redirect("/") # Call the userinfo API to get the user's information with a valid access token. # This is the first example of using the access token to access an API on the user's behalf. def get_user_info(access_token): response = requests.get("https://www.googleapis.com/oauth2/v3/userinfo", headers={ "Authorization": f"Bearer {access_token}" }) if response.status_code == 200: user_info = response.json() return user_info else: print(f"Failed to fetch user info: {response.status_code} {response.text}") return None @app.route('/logout') def logout(): session.clear() return redirect('/') # fetch all sheets within a Google spreadsheet def get_sheets(sheets_api, spreadsheet_id) -> list[str]: result = sheets_api.get(spreadsheetId=spreadsheet_id).execute() return [sheet["properties"]["title"] for sheet in result["sheets"]] # fetch the data for a given sheet within a Google spreadsheet def get_sheet_data(sheets_api, spreadsheet_id, sheet_title) -> list[list[str]]: result = ( sheets_api.values() .get(spreadsheetId=spreadsheet_id, range=sheet_title) .execute() ) return result["values"] # Render a form to allow importing a spreadsheet @app.route("/import_spreadsheet_form") def import_spreadsheet_form(): return """

Import Spreadsheet

""" @app.route("/import_spreadsheet", methods = ['POST']) def import_spreadsheet(): if 'access_token' not in session: return redirect('/signin') spreadsheet_id = request.form["spreadsheet_id"] credentials = google.oauth2.credentials.Credentials(token=session['access_token']) service = build("sheets", "v4", credentials=credentials) sheets_api = service.spreadsheets() try: sheets = get_sheets(sheets_api, spreadsheet_id) data_by_sheets = {} for sheet in sheets: data = get_sheet_data(sheets_api, spreadsheet_id, sheet) data_by_sheets[sheet] = data except googleapiclient.errors.HttpError as e: return f"upload failure" dirpath = os.path.join("static", "uploads", spreadsheet_id) filepath = os.path.join(dirpath, "data.json") os.makedirs(dirpath, exist_ok=True) with open(filepath, "w") as file: json.dump(data_by_sheets, file) return "upload success! Really!" @app.route('/') def welcome(): if "access_token" in session: user_info = get_user_info(session["access_token"]) if user_info: return f""" Hello {user_info["given_name"]}!
Your email address is {user_info["email"]}
Sign In to Google
Import a Sheet """ return """

Welcome to Google Sheet Importer

Sign In to Google
Import a Sheet """ if __name__ == '__main__': app.run(host='0.0.0.0', port=5000) ``` Remember, if you publish the app. Make sure to: 1. Added the production `/oauth2callback` URI for to the "Authorized redirect URIs". 2. Go to the [consent page](https://console.cloud.google.com/apis/credentials/consent) and "Publish App". Hope you had a good experience, and hope you Enjoy your further advantures. # Streaming native graphics using VNC Source: https://docs.replit.com/additional-resources/streaming-native-graphics-vnc Replit offers virtual network computing (VNC) functionality. VNC is a mature virtual desktop protocol that allows your Replit App to stream a native desktop to your web browser. This protocol allows native applications (developed in Python, Java, C++, etc.) to open desktop windows as they would on any physical computer. This streaming technology allows you to work with legacy applications in your browser from any device! For example, you could run a Python-powered game designed for desktop right on your mobile phone or tablet without making any changes to the underlying code. Tetris (powered by PyGame) image of Tetris in a Replit App ## How Can I Use VNC? Any Replit App – in any language – can use a virtual desktop. No changes are needed to execute native graphics programs on Replit. The VNC pane will appear when any application attempts to open a native desktop window. ## Securing Your Replit App By default, your VNC connection does not have a password and can only be accessed from [https://replit.com](https://replit.com) since the connection relies on the same authentication used for the WebSocket. If you need to access your Replit App via the external [noVNC](https://novnc.com) client, you can set a VNC password. Set a password in your Replit App [secrets](/core-concepts/project-editor/app-setup/secrets) configuration. `Secrets` is a secure place to store passwords without the fear of other users accessing your passwords. Setting `VNC_PASSWORD` will add enhanced security when connecting remotely. ## How Can I Use Fullscreen VNC? You must have secured your Replit App as instructed above to proceed with these steps. 1. Execute the following command in your "Shell" tab: ```sh theme={null} echo $REPL_ID ``` image showing the echo command 2. Construct your connection URL by replacing `REPL_ID` in with the output from above: `<\REPL_ID\>.id.repl.co` 3. Open the [noVNC client](https://novnc.com/noVNC/vnc.html) in a separate browser tab. 4. Open connection settings. open connection settings 5. Expand the WebSockets field. Enter your connection URL (`\.id.repl.co`) in the `host` field, and leave the `path` field empty. host 6. Change the `Scaling Mode` to `Remote Resizing`: scaling 7. Use the `runner` username and the password configured above when asked for credentials. ## Examples * PyGame * Python matplotlib * Java Processing # Cloud Aug 2026 Pricing Updates Source: https://docs.replit.com/billing/aug-cloud-billing-updates Starting **August 1, 2026**, Replit Cloud prices drop across all plans. The new prices apply automatically to all of your published projects at the start of your first billing cycle that begins on or after August 1, 2026. ## Price Comparison Table ### Deployments | Item | Unit | Current price | New price | | :- | :- | -: | -: | | Autoscale compute units | Per million compute units | \$3.20 | \$0.60 | | Autoscale requests | Per million requests | \$1.20 | \$0.40 | | Autoscale base fee | Per month | \$1 / mo | \$1 / mo | | Scheduled compute units | Per million compute units | \$3.20 | \$0.60 | | Outbound data transfer | Per GiB | \$0.10 | \$0.05 | ### App Storage | Item | Unit | Current price | New price | | :- | :- | -: | -: | | Data storage | Per GiB per month | \$0.03 | \$0.015 | | Basic operations | Per thousand operations | \$0.0006 | \$0.0004 | | Advanced operations | Per thousand operations | \$0.0075 | \$0.005 | Learn more about these categories in [App Storage Billing](/billing/object-storage-billing). ### Reserved VM Deployments | Configuration | Unit | Current price | New price | | :- | :- | -: | -: | | 0.25 vCPU / 1 GiB RAM (legacy) | Per hour | \$0.014 | \$0.0104 | | 0.5 vCPU / 2 GiB RAM | Per hour | \$0.028 | \$0.0208 | | 1 vCPU / 4 GiB RAM (legacy) | Per hour | \$0.042 | \$0.0486 | | Dedicated 1 vCPU / 4 GiB RAM | Per hour | \$0.055 | \$0.0486 | | Dedicated 2 vCPU / 8 GiB RAM | Per hour | \$0.11 | \$0.0694 | | Dedicated 4 vCPU / 16 GiB RAM | Per hour | \$0.22 | \$0.1806 | | Dedicated 8 vCPU / 32 GiB RAM (new) | Per hour | Not available | \$0.3611 | | Dedicated 16 vCPU / 64 GiB RAM (new) | Per hour | Not available | \$0.7222 | ### Database | Item | Unit | Current price | New price | | :- | :- | -: | -: | | Compute time | Per compute hour | \$0.16 | \$0.16 | | Data storage | Per GiB per month | \$1.50 | \$0.35 | Database compute prices are unchanged, while data storage prices decrease. Learn more in [Publishing and Database Billing](/billing/about-usage-based-billing). ## Frequently asked questions ### When do the new prices take effect? The new prices go live on **August 1, 2026**. Your account switches to the new prices at the start of your first billing cycle that begins on or after August 1, 2026. Because billing cycles renew throughout the month, the exact date depends on when your subscription renews. ### Which plans get the new prices? All plans: Replit Core, Replit Pro, Teams, and Enterprise. ### Do I need to change anything in my app? No. The new prices apply automatically. Your deployments, databases, and storage keep running without any action from you. ### Where can I see my current usage and charges? Visit the [usage page](https://replit.com/usage) to track your consumption and costs in real time. See [Managing Your Spend](/billing/managing-spend) to set spending limits and budgets. # Add a custom domain Source: https://docs.replit.com/build/add-custom-domain Move Velocity from velocity.replit.app to velocityrentals.com. By the end, Velocity will live at `velocityrentals.com` instead of `velocity.replit.app`. You've added sign-in, a database, payments, and a calendar integration to Velocity. Now give it a URL that looks like a real rental brand. This guide moves Velocity to `velocityrentals.com` — swap in whatever domain you own. ## Confirm Velocity works on the Replit URL first Don't change anything until the public `velocity.replit.app` URL is solid. Open it in a new browser tab and check: * The fleet page loads. * A customer can sign in, reserve a car, and see the reservation after refresh. * Stripe deposit checkout opens and the test card confirms the reservation. * The Google Calendar event lands on the booking customer's calendar. If any of those break, fix them before touching DNS. See [Troubleshoot publishing](/build/troubleshooting). ## Connect velocityrentals.com in Replit Open Velocity's Publishing settings and add `velocityrentals.com` as a custom domain. Replit will show you two DNS records — copy them exactly as shown. The Replit custom-domain dialog inside Velocity's Publishing settings with velocityrentals.com entered and the two DNS records (an A record and a TXT verification record) ready to copy Then open the dashboard at your domain provider (Namecheap, Cloudflare, Google Domains, GoDaddy, etc.) and add those exact records. If you'd like Agent to walk you through the steps for your specific provider: I'm moving Velocity from velocity.replit.app to velocityrentals.com. My domain is registered at \[name your domain provider].
Walk me through exactly which DNS records to add, in the order I should add them.
Use the values shown in Replit — don't make up record values.
Tell me how to check that the domain is connected before I expect it to work.
DNS changes can take a few minutes to a few hours to apply. Replit will show "Verified" next to `velocityrentals.com` once it sees the records. ## Test Velocity on velocityrentals.com Once Replit shows the domain as verified: 1. Open `https://velocityrentals.com` in a new browser tab. The green padlock should appear — HTTPS is automatic. 2. Sign in as a customer. Sign-in should still work (Replit Auth handles the new domain automatically). 3. Reserve a car, refresh, and confirm the booking persists. 4. Open Stripe deposit checkout. The page should now show `velocityrentals.com` as the merchant URL. 5. Confirm the booking and check that the Google Calendar event still lands on the customer's calendar. If sign-in, checkout, or the calendar integration misbehaves only on `velocityrentals.com`, tell Agent the exact symptom: Velocity works at velocity.replit.app but \[describe what's broken] on velocityrentals.com.
Tell me whether the fix is in DNS, in Replit's settings, or in a third-party provider's settings (like Stripe or Google).
Give me the safest next check.
Velocity now lives at a real rental-brand URL. Share `velocityrentals.com` with customers — they won't see "replit.app" anywhere. ## Improve it next Fix issues when the public URL doesn't work. Buy velocityrentals.com through Replit if you haven't already. ## Need further help? * **`velocityrentals.com` doesn't load right away:** DNS changes can take a few hours. Wait and check again before changing more settings. * **The Replit URL works but the custom domain doesn't:** double-check the DNS records match what Replit shows exactly — common mistakes are a trailing dot, an extra subdomain, or a stale record. * **Stripe checkout still says `velocity.replit.app`:** ask Agent to update the Stripe redirect URLs to use `velocityrentals.com`. * **You don't own a domain yet:** buy one through Replit — see [Domain purchasing](/build/domain-purchasing). ## Related * [Custom domains](/features/publishing/custom-domains) * [Domain purchasing](/build/domain-purchasing) # Add a database Source: https://docs.replit.com/build/add-database Make Velocity's cars, availability, and reservations stick around after refresh, restart, and publish. By the end, every Velocity car, availability slot, and reservation will still be there tomorrow. Velocity after refresh showing the signed-in customer's My bookings list with two saved reservations and the fleet page with cars in the same order, both unchanged from before the refresh You added sign-in to Velocity in [Add login](/build/add-login). But the cars in the fleet and the reservations customers make still disappear when the page refreshes — they only live in the browser. Add a database so everything persists. ## Tell Agent to save the data For Velocity, use Neon — Replit's managed Postgres database. Neon handles concurrent bookings cleanly, scales with real customer traffic, and Agent provisions it automatically with separate Development and Production environments. There's no Neon dashboard signup and no keys to paste. Save Velocity's data to a database so cars, availability, and reservations don't disappear on refresh.
Use Neon (Postgres).
Save: each car (make, model, year, daily rate, photo, location), each car's availability calendar, and each reservation (pickup date, return date, car, customer).
Attach every reservation to the signed-in customer so each person only sees their own.
Prevent the same car from being booked on overlapping dates.
Tell me what to test after the change.
Agent will provision a Neon database, move the fleet and reservations from in-memory data into it, and add the overlap check so the same Lamborghini can't get double-booked. Agent chat after the Neon migration showing the verification checklist — overlap-prevention, signed-out blocking, user-scoped bookings, invalid date rejection, bad-car rejection — and a Checkpoint made just now indicator, alongside the Velocity preview rendering with the persisted fleet ## Test that everything sticks 1. Sign in to Velocity in Preview and reserve a car for next Saturday. 2. Refresh the page. The reservation should still be there in "My bookings." 3. Restart the app from the Agent chat. The fleet and the reservation should both still be there. 4. Try to reserve the same car on the same Saturday with a second account. Velocity should say the car isn't available and offer a different date or car. 5. Sign out and sign back in. Your reservation should still be there. If a reservation disappears at any step, paste the exact symptom back to Agent: I reserved a car in Velocity, but the reservation disappears after refresh.
Check whether the reservation is being saved to the database or only stored in the page.
Fix the smallest issue and tell me how to verify it.
You can also ask Agent for a simple admin view to see what's in the database: Show me a simple admin page in Velocity that lists every car and every reservation in the database, grouped by car.
Only show it to me as the project owner.
## Publish and confirm on the public URL Agent's Neon setup gives Velocity separate Development and Production environments out of the box. Publish Velocity again from the Agent chat or the Publishing tile, then open the public URL in a new tab. Replit wires the Production Neon credentials into the published deployment automatically — make a reservation on the public URL, refresh, and confirm it's still there. Velocity now remembers every car, every available date, and every reservation. The next refresh won't lose a single booking. ## Improve it next Take a refundable deposit when a customer reserves a car. Send each booking to the customer's calendar. Turn the saved reservations into utilization charts. ## Need further help? * **Reservations save in Preview but not on the public URL:** ask Agent to confirm the Production Neon credentials are wired into the published deployment. * **Data is hard to inspect:** ask Agent to add a simple admin view that lists everything in the database. * **You want to seed the fleet:** ask Agent to add a one-time script that loads your real cars into the database. * **You want a zero-setup database for a quick prototype:** use [Replit Database](/features/data-and-storage/sql-database) instead — it's built into every Repl with no separate provisioning. ## Related * [Production databases](/features/data-and-storage/development-and-production) * [Replit Database](/features/data-and-storage/sql-database) # Add integrations Source: https://docs.replit.com/build/add-integrations Send every Velocity booking to the customer's Google Calendar. By the end, every Velocity reservation will land on the customer's Google Calendar with the pickup and return times already filled in. Integrations let Velocity talk to other tools. You could send each booking to the customer's calendar, email a coordinator when a high-value rental is reserved, or pull weather into the trip-planning page. Pick one for now — Google Calendar gives every customer a clear, verifiable artifact ("the rental is on my calendar"), and you can check it on your own calendar during testing. ## Tell Agent to add the calendar integration Replit ships a built-in **Google Workspace connector** that covers Google Calendar. Agent signs in to Google with a single click — there are no API projects to create, no OAuth credentials to copy, and no secrets to paste. After a Velocity customer confirms a reservation, add the rental to their Google Calendar.
Use Replit's Google Workspace connector for Google Calendar — don't ask me for any OAuth credentials.
The event title should be "Velocity rental: \[car make and model]".
The event should span pickup time to return time and include the pickup address and the reservation reference in the description.
Update the calendar event automatically if the customer changes the dates or cancels the reservation.
Add a clear message in Velocity if the calendar add fails, so the reservation still confirms.
Agent will provision the Google Workspace connector, open a single Connect dialog in the workspace, and after you sign in with the Google account that owns the calendar, wire Velocity to add an event every time a reservation is confirmed. Connectors are a Core, Pro, or Enterprise feature. On the free plan, ask Agent to use a Google OAuth project instead — you'll need to create a Google Cloud project, enable the Calendar API, and paste the resulting credentials into your app's Secrets pane. ## Test it end-to-end 1. Open your own Google Calendar in a new tab. 2. Sign in to Velocity in Preview. 3. Reserve a car for next Saturday-Sunday and confirm the booking. 4. Switch to your Google Calendar tab. A new "Velocity rental: \[car]" event should appear on Saturday-Sunday with the pickup address in the description. 5. Change the reservation in Velocity to Sunday-Monday. The calendar event should move automatically. 6. Cancel the reservation. The calendar event should disappear. 7. As a second test, open **Integrations** in the workspace and disconnect Google Workspace, then try to book. Velocity should still confirm the reservation and show a clear message like "Couldn't add to your calendar — your reservation is confirmed." Reconnect the connector once the test passes. If the reservation confirms but no event appears, paste the exact error back to Agent: The integration failed with this error: \[paste the error from Velocity or the Replit logs].
Tell me the likely cause and fix the smallest issue.
Make sure reserving a car still works in Velocity even if Google Calendar is unreachable.
## Publish and try it from the public URL Once the calendar integration works in Preview: 1. Publish Velocity again from the Agent chat. 2. Open the public URL and book a car from a real customer's perspective. 3. Confirm the event appears on the calendar of the account that booked. 4. Update and cancel a booking from the public URL and confirm the calendar event follows. Customers now leave Velocity with the rental already on their calendar. The reservation isn't just a confirmation email — it's an event they can't forget. ## Improve it next Move Velocity to a branded URL customers can share. Take a refundable deposit at booking. ## Need further help? * **No event appears in Google Calendar:** open **Integrations** in the workspace, confirm the Google Workspace connector shows Connected, and that the Calendar scope is granted. * **The connector shows Connected but events still don't land:** ask Agent to log the calendar payload it sends, then fix the field mapping. * **Date or address fields land in the wrong place on the event:** ask Agent to log the event shape it sends, then fix the field mapping. * **You want a different integration:** swap "Google Calendar" for any other connector — Slack notifications for the team, HubSpot to log customers as CRM contacts, Airtable to track bookings in a shared base. Agent handles each the same way through the Integrations pane. ## Related * [Integrations](/features/integrations/overview) * [Replit AI integrations](/features/integrations/replit-ai-integrations) # Add login Source: https://docs.replit.com/build/add-login Let each Velocity customer sign in to see their own bookings and saved cars. By the end, each Velocity customer will sign in and see only their own bookings and saved cars. Velocity home screen after sign-in showing the customer name in the top-right header, the My bookings section with one upcoming reservation, and the saved-cars row underneath You saw Velocity on [Welcome to Replit](/welcome) — a premium supercar rental app. Right now anyone visiting the public URL can see every reservation. No one books a Lamborghini anonymously. Add sign-in and each customer gets their own bookings and saved cars. ## Tell Agent to add sign-in For Velocity, use Clerk. Replit's Clerk integration gives your app its own branded sign-in screen, customer accounts that exist inside Velocity (not Replit accounts), and full control over the look and feel — fitting for a premium rental brand. Agent provisions everything automatically, so there is no Clerk dashboard signup and no keys to paste. Add sign-in to Velocity so each customer has their own bookings and saved cars.
Use Clerk Auth.
Keep the car-browsing pages public so visitors can still explore the fleet without an account.
Require sign-in before someone can reserve a car or save one to their favorites.
After sign-in, show the customer's name in the header and a "My bookings" section with only their reservations.
Add a sign-out button.
Give me a test checklist using two different customers.
Agent will provision a Clerk tenant for Velocity, add the sign-in components, gate the booking flow behind it, attach each reservation to the signed-in customer, and add sign-out. Watch the build in the Agent chat. ## Test it with two customers One account isn't enough — you need two so you can prove bookings stay separate. 1. Open Velocity in Preview and browse cars without signing in. The fleet should still be visible. 2. Click Reserve on a car. You should land on the Clerk sign-in screen. 3. Sign up with your own email and complete a reservation (e.g. a weekend booking on a 911). 4. Sign out. The "My bookings" section should disappear and the booking flow should ask for sign-in again. 5. Open Preview in an incognito window and sign up with a different email. Reserve a different car. 6. Switch back to your first window, sign in, and confirm you still see your own reservation — not the second customer's. If both customers see the same reservations, the bookings aren't yet attached to the signed-in person. Tell Agent the exact symptom: Both customers can see each other's reservations in Velocity.
Attach each booking and each saved car to the signed-in customer so each person only sees their own.
Show me how to verify it with two test accounts.
## Publish and sign in on the public URL Publish Velocity again from the Agent chat or the Publishing tile, then open the public URL in a new tab and sign in. Clerk is provisioned with separate Development and Production environments — Agent wires the Production credentials into the published app automatically, so sign-in works on the public URL out of the box. Velocity now has real customers. Each one signs in to a personal garage of bookings — nobody else sees them. ## Improve it next Make cars, availability, and reservations persist between sessions. Take a refundable deposit when a customer reserves a car. ## Need further help? * **The whole app is hidden:** ask Agent to keep car browsing public and protect only the booking and account pages. * **Customers see each other's reservations:** ask Agent to attach each booking and saved car to the signed-in customer. * **Sign-in works in Preview but not after publishing:** open the public URL in a new tab and tell Agent the exact error you see. Make sure Agent provisioned the Production Clerk environment. * **You want a faster zero-config sign-in for prototypes:** Replit Auth uses your customers' Replit accounts with no Clerk tenant to manage — see [Replit Auth](/features/auth-and-identity/authentication). ## Related * [Clerk Auth](/features/auth-and-identity/clerk-auth) * [Replit Auth](/features/auth-and-identity/authentication) # Add payments Source: https://docs.replit.com/build/add-payments Take a refundable deposit when a customer reserves a Velocity car, then charge the balance on pickup. By the end, a Velocity customer will pay a refundable deposit to reserve a car and pay the balance at pickup. You added sign-in and a database to Velocity. Now turn it into a real booking business: hold each car with a refundable **deposit at booking**, then **charge the balance on pickup**. Replit handles payments through Stripe — you don't write any Stripe code yourself. ## Decide the deposit and balance amounts Before asking Agent to build, pick the math: * **Deposit at booking:** a flat amount or a percentage of the total? A flat \$500 is simpler to communicate; 20% scales with the car. * **Balance at pickup:** the rest of the rental cost, charged when the customer collects the keys. * **Refund window:** how late can someone cancel and still get their deposit back? 48 hours is a common default. For this guide, Velocity holds a flat \$500 refundable deposit at booking, charges the balance at pickup, and refunds in full if a customer cancels more than 48 hours out. Adjust to whatever fits your real business. ## Tell Agent to add Stripe checkout Add deposit-and-balance payments to Velocity using Stripe in test mode.
At booking, take a \$500 refundable deposit and save the customer's payment method on file.
At pickup, charge the remaining balance to the saved payment method.
If the customer cancels more than 48 hours before pickup, refund the deposit in full. Inside 48 hours, keep it.
Save the deposit status and the saved-card reference in the database so a customer can see both on their booking.
Tell me exactly which secret keys I need to paste from Stripe and where to paste them.
Give me a test checklist for the deposit success, deposit cancel, balance charge, and cancellation refund cases.
Agent will set up Stripe under the hood, add the deposit and balance flows, and tell you which secret keys to grab from Stripe. Paste them into your app's settings when Agent asks — your test keys live there, never in the code. Replit Secrets pane showing the Stripe API keys (STRIPE_SECRET_KEY, STRIPE_PUBLISHABLE_KEY, STRIPE_WEBHOOK_SECRET) that Agent told the builder to paste ## Test the full flow in test mode Stripe gives you a special test card so you can run real-feeling payments without spending real money: `4242 4242 4242 4242`, any future expiry, any 3-digit CVC. 1. Sign in to Velocity in Preview and reserve a car for next Saturday-Sunday. 2. At checkout, you should see "Deposit today: $500" and "Balance at pickup: $1,900" (or whatever your math produces). 3. Pay the deposit with the `4242` test card. You should return to a confirmation page showing the deposit paid and a payment method saved for the balance. 4. Open the booking from "My bookings" and use the admin or pickup action to charge the balance. Confirm the balance shows as paid. 5. Make a second reservation, then cancel it more than 48 hours out. The deposit should refund to the test card (you can verify in your Stripe test-mode dashboard). 6. Make a third reservation and cancel inside 48 hours. The deposit should be kept and clearly explained to the customer. 7. Try checkout with Stripe's decline test card (`4000 0000 0000 0002`). The reservation should not be confirmed and the customer should see a clear failure message. If the deposit succeeds but the reservation doesn't get confirmed, tell Agent: The Stripe test deposit for Velocity succeeded but the reservation isn't showing as confirmed.
Connect the deposit-success event to the reservation status in the database.
Show me how to verify it with another test booking.
## Switch to live payments when you're ready Test mode is for you. Live mode is for real customers handing over real money. When Velocity is ready: 1. In Stripe, switch from test mode to live mode and copy the **live** secret keys. 2. In your app's settings, replace the test keys with the live ones. 3. Publish Velocity again from the Agent chat. 4. Open the public URL, book a low-cost test car with your own real card, and confirm both the deposit and the balance flow work end-to-end. Run that real-card test once before sharing the public URL widely. Velocity now takes real bookings with real money. ## Improve it next Send each booking to the customer's calendar. Move Velocity to a branded URL before charging customers. ## Need further help? * **Deposit succeeds but the reservation isn't confirmed:** ask Agent to connect the Stripe success event to the reservation status in the database. * **Test mode works, live mode doesn't:** make sure you replaced the test keys with the live ones in your app's settings. * **You want one upfront payment instead of deposit + balance:** tell Agent to switch Velocity to a single full payment at booking. * **You want recurring subscription pricing (monthly access to the fleet):** Replit also supports RevenueCat — ask Agent to use it instead of Stripe. ## Related * [Stripe payments](/features/monetization/stripe-payments) * [RevenueCat subscriptions](/features/monetization/revenuecat-subscriptions) # Build and publish from a template Source: https://docs.replit.com/build/build-and-publish-from-template Start from a Replit Design template, turn the selected frame into a functional website with Agent, test it in Preview, and publish a live URL. ⏰ *Estimated time: 10 minutes* By the end of this guide, you will have a small app published at a URL you can share. The selected template built as a website and open at its public Replit URL You will start with a polished template, turn it into a functional website, and publish it. The exact templates available may change, so choose one that fits what you want to make. ## Before you start You need a [Replit account](https://replit.com). Building a new app from a Design frame requires Core or Pro. See [Build your design](/design/build-your-design) and [Billing](/billing/ai-billing) for plan details. The goal is to finish one complete loop: * Choose a template in [Replit Design](https://replit.com/design), * Build it with [Agent](/features/agent/overview), * Test the app, * Publish, and share. Agent is Replit's AI builder. You describe what you want, and Agent helps create, explain, and fix the app. ## Choose, build, and publish a template Open [replit.com/design](https://replit.com/design). Browse the featured templates or filter by **Landing Pages**, **Mobile**, **Prototypes**, and other formats. The Replit Design gallery with featured templates and format filters Select a template to inspect it, then select **Use template**. Replit creates a new project and places the template on the Design canvas. If you started from a template's cover page instead, see [Start from a template](/design/start-from-a-template) for the remix flow. A Replit Design template preview with the Use template button The remixed template opens on the Design canvas inside its new project. The selected template remixed onto the Design canvas in a new Replit project A template starts as a design mockup. Before it can be published, switch to **Build** and ask Agent to turn the selected design into a functional website. For example: > Build this selected template as a functional website. Preserve its visual design and make its navigation and contact actions work. Agent creates a website artifact in the same project and uses the selected design as its source. The **Publish** button is also visible in Design. If the project contains only design mockups, Publishing reports that there is nothing to deploy yet and directs you to ask Agent to build an app. After a Website artifact exists, you can publish from either Design or Build. The Build workspace with a selected portfolio design attached, the build request in Agent chat, and Publishing explaining that a design-only project has nothing to deploy yet When Agent finishes, open [Preview](/features/editor/preview) and use the app like a visitor. Preview is where you test the app while you are building, before publishing it. Check that you can: * Follow the main navigation. * Use the template's buttons and forms. * See a clear success or validation state after an action. * Refresh the page and use the site again. * Resize Preview to a phone-sized width. If something breaks, describe the symptom to Agent. You do not need to diagnose the code yourself. The template-based website running in the Project Editor Preview Want to explore visual variations before publishing? See [Explore suggestions](/design/explore-suggestions) to generate alternative looks side by side and apply the one you like. When Preview works, select **Publish**. Confirm the generated subdomain, choose who can access the app, and review the security settings. Then select **Publish** in the dialog. Publishing creates a public version of your app with a URL you can share. The Publish dialog with the generated subdomain, access settings, and Publish button Open the public URL in a new browser tab and repeat the same checks. The app should work outside the Project Editor before you share it. If the published app behaves differently from Preview, check the publishing logs and any production settings the app needs. For common publishing problems, see [Troubleshoot publishing](/build/troubleshooting). The completed template-based website open at its public Replit URL ## 🎉 Congratulations — you shipped your first app You went from a design template to a live, shareable URL. Along the way you: * Chose and remixed a template from Replit Design. * Asked Agent to turn the selected design into a functional website. * Tested the result in Preview. * Published the app and opened it at its public URL. That's a complete Replit workflow — choose a starting point, build, test, improve, and publish. ## Next steps
Design with Canvas

Explore visual variations and apply a new design without rebuilding.

Explore Design →
Build in parallel

Run multiple Agent tasks at once so different parts of the app move forward together.

Learn more →
Vibe coding 101

Learn how to guide Agent from idea to working app.

Open the guide →
Add a database

Save app data after refresh.

Continue →
# Build with Free Mode Source: https://docs.replit.com/build/build-with-free-mode Use your included Free Mode allowance to turn an idea into a working app, one focused step at a time. ## Build your first version with Free Mode Use Free Mode to move an idea into a working first version without using credits. Choose **Free** from the mode selector below the prompt box before you start building. Mode selector with Free selected ## Build in focused steps Free Mode works best when you give Replit one clear next step at a time. Start with the version of your app that proves the idea, then build on it. 1. **Describe what you want to build.** Start with the outcome, the people it is for, and the first thing it needs to do. 2. **Build the essential flow.** Ask for one screen, feature, or interaction at a time instead of every possible feature at once. 3. **Preview and refine.** Test what Replit creates, then ask for the next improvement with the result in front of you. 4. **Keep the context.** Continue in the same conversation so Replit can build on your decisions and the app you already have. For example, you might begin with: “Build a simple running tracker where I can log a run, see my weekly total, and add a goal.” Then refine the interface, add data, and test each step as you go. ## Make the allowance go further * Break a larger feature into small, testable requests. * Tell Replit what to change and what to keep, especially when refining an existing screen. * Use follow-up questions to clarify the plan before building a more involved feature. * Return to a project with a concrete next step, such as adding validation, improving a mobile layout, or connecting a form. ## Check your allowance Open **Settings** → **Usage** to see how much of your Free Mode allowance remains and when it will refresh. Settings Usage page with the Free allowance panel visible When you need more capability, want to select a specific model, or have reached your Free Mode allowance, switch to **Power Mode** or **Max Mode**. Those modes use monthly credits. ## Keep going * [Get the most out of Free Mode](/chat/free-mode): Learn how Free Mode fits everyday chat, creation, and building. * [Build your first app](/build/your-first-app): Practice the prompt, build, test, and refine loop. * [Select the right Agent Mode](/chat/agent-modes): Choose between Free Mode, Power Mode, and Max Mode. # Connect via MCP Source: https://docs.replit.com/build/connect-via-mcp Connect Replit Agent to external tools, data sources, and APIs through the Model Context Protocol (MCP) — sign in to a pre-listed server or add a custom one. Replit Agent can connect to hundreds of external tools and data sources through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io) — an open standard for AI tool integrations. Sign in to a pre-listed server or add any custom MCP server you trust. ## Connect a pre-listed MCP server Replit ships with a curated list of MCP servers for popular services like Stripe, Linear, Notion, Sentry, and more. Connecting is a single sign-in click. MCP Servers for Replit Agent settings pane listing pre-listed servers including Stripe, Linear, Notion, Sentry, Atlassian, Miro, PostHog, Amplitude, Mixpanel, Granola, and Razorpay — each with a Sign in button Go to [replit.com/integrations](https://replit.com/integrations) and scroll to **MCP Servers for Replit Agent**. Find the service you want to connect — Stripe, Linear, Notion, Sentry, Atlassian, Miro, PostHog, Amplitude, Mixpanel, Granola, Razorpay, and others. Click **Sign in** next to the server. You'll be guided through the OAuth flow with that service. Once connected, the server's connection status updates and Agent can use its tools. For the full catalog, see the [MCP Servers reference](/features/mcp/overview). ## Add a custom MCP server If the server you want isn't in the pre-listed catalog, add it by URL. Connect an MCP server dialog showing Display name field, MCP Server URL field, and Advanced settings expandable section On the MCP Servers settings pane, click **+ Add MCP server**. Provide a recognizable name — Agent uses it to reference the server in chat logs. Paste the MCP server's HTTPS endpoint. Open **Advanced settings** to add custom headers (e.g. `X-API-Key`) if the server needs authentication. Click **Test & save**. Replit attempts to connect and walks you through any OAuth flow the server requires. Once saved, the connection appears under MCP Servers with its status. Only connect to MCP servers you trust. A connected server can provide tools and data to Agent — review the source before adding any unfamiliar endpoint. ## Use MCP tools in Agent After a server is connected, Agent automatically fetches its tool list and makes the capabilities available across all your projects. To use a server, just mention it in chat: > Use the Notion MCP server to find the most recent meeting notes. Agent calling a custom MCP server's tools in chat Agent picks the right tools from the server based on your request. If a tool requires confirmation, you'll see a prompt before it runs. ## Share an install link Install links let anyone add your MCP server to Replit with a single click — useful for documentation, READMEs, or anywhere you want to promote your integration. Use the form below to generate an install link and a clickable badge for your server: For the link format, see the [install link reference](/features/mcp/overview#share-your-own-install-link). ## Next steps Understand what MCP is, how it works, and the capabilities it unlocks for AI. Browse the curated list of MCP servers with one-click install buttons. # Create a team workspace Source: https://docs.replit.com/build/create-a-team-workspace Create a Team Workspace on Replit, invite members during setup, and manage who has access to your team's projects. By the end, you'll have a team workspace with members who can collaborate across every project inside it. A **team workspace** lets a regular group — a startup team, a class, or a client project — work across multiple projects together. Members get access to all projects in the workspace, so you don't invite them one by one. The admin manages billing and settings centrally. If you're not sure whether a team workspace is the right fit, see [Personal & Team Workspaces](/features/collaboration/team-workspaces) for the difference between the two, when to use each, and plan availability. ## Create a team workspace Create a new workspace form with a generic workspace name and a blank field for inviting team members In the home page, click your workspace name in the top-left corner. Select **Create workspace** and choose a name for your team workspace. Enter one or more email addresses (comma-separated) in the invite field. Invitees receive an invitation and gain access to all projects in the workspace once they accept. ## Manage members If you didn't invite members during setup, or need to add more later, go to **Settings > Workspace collaborators** in your team workspace and invite members by email or Replit username. Invite a user dialog with a blank field for entering email addresses From the **Settings** page you can also: * **Remove members** to revoke their access to all workspace projects. * **Transfer projects** from personal workspaces into the team workspace — see [Transfer app to teams](/teams/identity-and-access-management/transfer-app-to-teams). For advanced identity management, role-based access, and group permissions, see [Pro and Enterprise](/category/teams). ## Next steps Invite people to a specific project and build together with Agent. Understand the difference, choose the right type, and review plan availability. Enterprise features: SSO/SAML, groups, permissions, and audit logs. # Create a dashboard from data Source: https://docs.replit.com/build/dashboard Turn a public CSV, spreadsheet, database, warehouse connector, or API into a dashboard that answers a clear question. A dashboard helps someone make a decision from data. If you want to explore a question before building an app, you can [create charts directly in Chat](/chat/create-charts). Use this guide when you want a dashboard with its own interface, charts, and filters. You will build a **Global Progress Explorer** from a public CSV: country-level data with year, population, continent, life expectancy, and GDP per capita. ## What you'll achieve By the end of this guide, you will have: * A Global Progress Explorer dashboard built from a realistic public CSV. * Summary metrics for countries, population, life expectancy, and GDP per capita. * Charts and filters that show how progress changed over time. * A way to verify that the dashboard numbers match the source data. * A shareable or publishable dashboard for stakeholders. ## What you'll learn You will learn how to: * Start with a decision, not a chart type. * Ask Agent to build a dashboard from a public CSV. * Check calculations against the underlying data. * Add filters and an insights summary. * Decide when a dashboard needs login, refresh, exports, or connected data. ## Who this is for Use this guide if you have customer, sales, product, operations, research, or public data and need a dashboard people can understand. This is useful for analysts, operators, founders, PMs, educators, and teams who need to turn raw data into decisions. ## Define the decision Before building, write down the decision the dashboard should support. For the global progress dataset: * **Question**: Where did life expectancy and GDP per capita improve over time? * **Audience**: education, research, strategy, or nonprofit teams. * **Useful metrics**: country count, year range, latest median life expectancy, total population represented, and median GDP per capita. * **Useful filters**: continent, country, and year range. If you cannot state the decision, the dashboard will become a collection of charts instead of a useful tool. ## Choose charts for your app For illustrated examples of chart types, see [Charts](/features/agent/charts). That reference shows charts in Chat; the prompts below describe charts to build into your app. Describe the question each chart should answer, along with its data source, units, and grouping: | Chart | Use it to | Example request | | - | - | - | | Line | Track a measure over time | “Add a line chart of monthly revenue, with one line per region.” | | Bar | Compare categories | “Add a bar chart of total orders by product category.” | | Stacked area | Show how a total and its parts change over time | “Add a stacked area chart of daily active accounts by plan.” | | Scatter or bubble | Explore relationships between measures | “Compare GDP per capita and life expectancy, with bubble size representing population.” | Ask Agent to add descriptive axis labels and units. Specify whether the app should sum, average, or count records before plotting them. For interactive charts, describe what each control should do: > Add a date range filter that updates every chart and summary card. Show the exact value when I hover over a data point. Test each filter against the source data. Ask for an empty state when no records match, rather than displaying misleading zero values. ## Build from a public CSV Use a positive public dataset with meaningful fields and enough rows to explore. Dataset: [Gapminder global progress CSV](https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv) Ask Agent to build the dashboard from that CSV: Build a Global Progress Explorer dashboard from this public CSV:
[https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv](https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv)
The dashboard should help an education or research team understand how life expectancy, population, and GDP per capita changed across countries and continents from 1952 to 2007.
Include summary cards for total countries, year range, latest median life expectancy, total population represented, and latest median GDP per capita.
Add a line chart for life expectancy over time by continent.
Add a bubble chart where GDP per capita is on the x-axis, life expectancy is on the y-axis, bubble size represents population, and color represents continent.
Add a bar chart showing the countries with the largest life expectancy gains between their first and latest year in the dataset.
Add filters for continent, country, and year range.
Include a short insights summary that explains the biggest patterns and which regions or countries improved most.
Show how key metrics are calculated so I can verify the numbers.
Make the dashboard polished, responsive, and easy to read on desktop and mobile.
## Check your work Open Preview and verify the dashboard before sharing it. Check that: * Total countries matches the number of unique countries in the CSV. * The year range shows 1952 to 2007. * Latest median life expectancy uses the latest year in the dataset. * Population totals use the filtered countries and years. * Filters update the summary cards and charts. * The bubble chart uses GDP per capita, life expectancy, population, and continent correctly. * The insights summary matches what the charts show. * The dashboard works on a phone-sized screen. If a number looks different than expected, ask Agent to show the calculation. The latest median life expectancy looks different than I expected.
Show me how you calculated it from the CSV.
Check that you used only rows from the latest year in the filtered data.
Update the calculation if needed and tell me how to verify it.
## Add filters and exports After the first dashboard works, ask Agent for the interaction that helps the audience explore the data. Add an exploration panel for the global progress dashboard.
Let me filter by continent, country, and year range.
Add a button to export the filtered chart data to CSV.
Keep the summary cards and insights summary in sync with the filters.
Dashboards can also support PDF export, chart CSV export, refresh, auto-refresh, light/dark mode, and analysis summaries. See [Data Visualization](/features/artifact-types/data-apps) for the concept overview. ## Use connected data when needed Use a public CSV when you are learning or prototyping. Use a connected data source when the dashboard should stay up to date. You can connect dashboards to: * A Replit app database. * A warehouse connector like BigQuery, Databricks, or Snowflake. * Analytics tools like Segment, Amplitude, or Hex. * External APIs. For warehouse data, ask Agent to explain the fields and queries it uses. Create a growth dashboard using our warehouse connector.
Identify the customer, product usage, billing, and retention fields needed.
Build charts for active customers over time, account growth by segment, and expansion revenue by plan.
Explain the fields and calculations you used so I can verify the dashboard.
For setup and availability details, see [Data Connectors](/connectors/warehouses/overview). ## Share the dashboard Share the dashboard when the numbers are trustworthy. If the dashboard uses private customer or business data, add access control before sharing widely. For public or sample data, you can publish and share the URL directly. Ask reviewers: > Review the global progress dashboard and tell me which region or country story you would highlight first, and why. ## You're done when * The dashboard loads the public CSV. * Summary cards and charts answer the progress question. * You verified at least one key metric manually. * Filters update the dashboard correctly. * The insights summary matches the data. * You know whether the dashboard should stay public, require login, or connect to live data. ## Next steps Put the dashboard behind authentication so only the right people see it. Save data so it persists and refreshes between sessions. Pull in another data source or push insights to existing tools. Connect a live warehouse so the dashboard reflects up-to-date data. Ask Agent to create a stakeholder presentation from the dashboard's findings. ## Need further help? * **Numbers look different than expected:** ask Agent to show the query, formula, or transformation. * **The CSV is unavailable:** check the URL, network access, and CSV headers. * **Filters do not update charts:** ask Agent to connect filters to both summary cards and chart data. * **The dashboard is slow:** ask Agent to summarize data, add filters, or reduce rows loaded on startup. * **The dashboard uses private data:** add login before sharing broadly. ## Related * [Data Visualization](/features/artifact-types/data-apps) * [Data Connectors](/connectors/warehouses/overview) * [Add login](/build/add-login) * [Add integrations](/build/add-integrations) # Purchase a domain Source: https://docs.replit.com/build/domain-purchasing Learn how to purchase a domain and connect it to your published app directly from Replit. Turn your apps into live, professional websites with custom domain names. Domain Purchasing lets you search, buy, and connect domains for your Replit published apps—all from within the platform. Go from published app to professional web presence in minutes. That means you can buy a site, like `my-app.com`, and have it automatically point to your app. Domain search interface showing available domains with extensions like .com and .ai We're eager to hear your feedback on how we can improve Domain Purchasing! ## Features Domain Purchasing streamlines the process of giving your apps professional web addresses. Instead of juggling multiple services, you can complete your entire web presence setup within Replit. Domain management interface showing purchased domains and their connection status Key capabilities include: * **Domain search and availability**: Check domain availability across popular extensions like `.com`, `.ai`, and more * **One-click purchasing**: Buy domains directly through Replit using your account's default payment method * **Automatic configuration**: Your domain instantly points to your Replit app without manual DNS setup * **WHOIS privacy protection**: Your personal information stays private in public domain records—included by default with every domain purchase * **Custom DNS records**: Add custom A, TXT, and MX records to configure email providers and other services * **Instant publishing**: Your app becomes accessible at your custom domain immediately after purchase * **Automatic renewals**: Domains renew automatically so your apps stay published without interruption ## Usage ### Purchasing domains 1. Publish your app and navigate to the Publish icon **Publishing** tab 2. Select the **Domains** tab 3. Choose **Buy a domain** to start the search process 4. Enter your desired domain name in the search bar 5. Review available options across different extensions 6. Select your preferred domain and complete the purchase When you purchase a domain, it automatically configures to point to your Replit app. Your app becomes accessible at the custom domain instantly, with no additional setup required. You will be billed for the domain purchase through your Replit account, deducted from your account balance then applied to your usage. ### Managing purchased domains Your domains integrate seamlessly with your published apps: * **Automatic renewals**: Domains renew automatically to keep your apps published * **Integrated billing**: Domain costs appear on your Replit billing alongside other services * **Transfer support**: Move domains between Replit accounts or to external registrars when needed ### Custom DNS records For domains purchased through Replit, you can add custom DNS records to configure additional services like email providers. The following DNS record types are supported: * **A records**: Point your domain or subdomain to a specific IP address * **TXT records**: Add text-based verification records for services like email authentication (SPF, DKIM, DMARC) * **MX records**: MX (Mail Exchange) records tell email servers where to deliver email for your domain. Setting up MX records allows you to use your custom domain for email addresses like `hello@yourdomain.com`. To manage DNS records for your purchased domain: 1. Navigate to the **Domains** tab in your Publishing Publish icon 2. Find the domain you want to configure 3. Select the **Edit** pencil icon icon 4. Choose **Add DNS Record** 5. Enter the record type, name, value, and TTL as required by your service provider This short video walks through finding the management page for your domain DNS records: