Introduction
Features
Integrations
Tips & tricks
Prompt Engineering
Troubleshooting
Actionable steps to resolve issues in your development lifecycle.
“Try to Fix” error loops
Building with Lovable makes coding faster and more intuitive—but even the best AI development tools can occasionally hit a snag. Sometimes your code won’t run as expected, or you might notice unexpected behavior where the AI interprets your intent incorrectly.
Here’s a step-by-step guide to help you navigate issues and get back on track:
Use the Try to Fix Button First
Click the Try to Fix button when an error shows up. Lovable will scan your logs, detect the issue, and attempt a quick fix. It’s your fastest first move. If that doesn’t work, it’s time to dig deeper.
Diagnose Unexpected Behavior
Your code may run without errors but not behave as intended. That’s unexpected behavior—harder to spot and harder to fix. Try this:
- Review your original prompt to confirm your instructions.
- Break it down: Check individual components and logic.
- Add visuals: Use screenshots to clarify what went wrong.
Write More Effective Prompts
Clear, structured prompts lead to better results. Use this format:
- Project Overview – What are you building?
- Page Structure – List key pages/components.
- Navigation Logic – Describe user flow.
- Visual Aids – Upload wireframes or screenshots.
- Implementation Steps – Lay out the build order.
Build in Logical Order
Structure matters. Follow this recommended flow:
- Create layout and pages.
- Connect Supabase or your backend.
- Set up authentication and user roles.
- Plan and organize feature logic.
- Prompt Lovable to implement features.
Use Chat-Only Mode for Clarity
When unsure, switch to Chat-Only Mode:
- Ask Lovable to analyze your project state.
- Request a recap of attempted solutions.
- Prompt for new directions to solve persistent problems.
If You're Still Stuck: Advanced Tactics
Still no luck? Try this:
- Be exact – Describe the bug and your expectations clearly.
- Use images – Screenshots or videos help illustrate problems.
- Ask directly – “What else can we try?”
- Rollback – Restore to a working version and rebuild incrementally.
What’s Going Wrong? Common Troubleshooting Areas
Troubleshooting generally falls into these categories:
- UI or Layout Glitches
- API or Backend Issues
- Prompt Misinterpretations
- AI Unresponsiveness or Misbehavior
- Platform or Integration Errors
Use the accordions below to identify specific issues and actions:
General issues
Jump into Chat-Only Mode and type: “Something’s off. Can you walk me through what’s happening and what you’ve tried?”
- Check component hierarchy and styles.
- Use screenshots to explain visual bugs.
- Prompt Lovable with: “Why is this element misaligned? Fix it.”
- Ensure your API schema is current.
- Validate environment variables and credentials.
- Ask Lovable: “What methods are being used in this call?”
- Prompt: “Take a step back. Analyze the error and suggest a different approach.”
- Break the task into smaller parts.
- Use the revert button if errors persist.
This should not happen.
Common Loading Issues
- Infinite loading: The project gets stuck in a loading state
- Preview not updating: Changes don’t appear in the preview window
- Error screen: Red error messages appear instead of your app
- Blank screen: The preview window shows nothing
Troubleshooting Steps
- Refresh the browser window and try again
- Check for console errors (use Dev Mode)
- Look for syntax errors in your code
- Check if your app has an infinite loop
- Ensure your index file exports a valid React component
- Make sure your app has a proper routing configuration
Quick fix for blank screens:
Often, a blank screen is caused by an error in your root component or routing configuration. Check for errors in your console and fix any syntax or import issues.
Please report it to the support team.
This should not happen. Please report it to the support team.
Try a hard refresh. If unresolved, contact support.
Common Dependency Problems
- Module not found: Package not installed or import path incorrect
- Version conflicts: Incompatible versions of related packages
- Peer dependency warnings: Missing or incompatible peer dependencies
- Duplicate packages: Multiple versions of the same package
- Build errors: Package doesn’t support your environment
Solutions for Dependency Issues
- Install missing packages using the
<lov-add-dependency>
command - Check for typos in import statements
- Verify the package name and version in package.json
- Install peer dependencies when prompted
- Check for compatibility with your React and TypeScript versions
- Look for alternative packages if one doesn’t work well
Working with shadcn/ui
Lovable comes with shadcn/ui pre-installed. Remember that:
- shadcn/ui components are imported from
@/components/ui/
- You can use all components in the shadcn/ui documentation
- Don’t modify the shadcn/ui component files directly
- Create wrapper components if you need custom behavior
Common Navigation Problems
- Page not found: Routes not properly configured
- Navigation fails: Links not working correctly
- Full page reloads: Using
<a>
instead of React Router’s<Link>
- Parameters not accessible: Route params not being extracted
- Nested routes issues: Problems with nested route definitions
How to Fix Navigation Issues
- Verify that all routes are correctly defined in your router configuration
- Use
<Link>
from react-router-dom instead of<a>
tags - Check path spellings in your route definitions
- For dynamic routes, ensure parameters are correctly defined with
:paramName
- Use
useParams()
to access route parameters - For programmatic navigation, use
useNavigate()
hook
Navigation Best Practices
- Organize routes logically based on your application structure
- Consider using lazy loading for routes to improve performance
- Add proper error handling for invalid routes (404 pages)
- Use
useLocation()
to read query parameters - Implement route guards for protected routes if needed
AI Reliability
- Keep prompts clear and structured.
- Use reverse meta prompting.
- Test in Chat-Only Mode before applying big changes.
This shouldn’t happen. Please report it to the support team.
Adjust your prompt to help the AI understand your goal or ask for step-by-step debugging help.
Make small, incremental changes. If the issue persists, roll back to a stable version or debug in chat.
Revert to a stable version and provide more context in your next prompt. Use visual editor or attach a knowledge file.
The AI might be editing the wrong files or misinterpreting. Be very specific or edit manually.
This was fixed by engineering. Please report if it happens again.
- Don’t retry the same prompt. Simplify or rephrase.
- Ask: “What fixes have we already tried?”
- Rebuild from a previous working state.
Core functionalities
- Likely a runtime error. Check browser console logs.
- Use chat to troubleshoot.
- Try a hard refresh or revert.
Report to the support team if you can’t revert your project.
This action isn’t currently supported.
This issue has been resolved. Report it if it recurs.
Shouldn’t happen. Contact support.
Shouldn’t happen. Report to the support team.
This is a serious issue likely related to our email provider. Contact support immediately.
Reach out to support directly.
- Break up large changes into smaller steps.
- Restart your browser if it slows down.
- If it persists, report your use case to support.
Using the Console for Debugging
- Accessing the console: Right-click → Inspect → Console tab
- Viewing errors: Red error messages in the console
- Adding console logs: Use
console.log()
,console.error()
, etc. - Filtering messages: Use the dropdown filters in the console panel
Effective Console Debugging
- Log variable values at different points in your code
- Use
console.table()
for displaying arrays or objects - Group related logs with
console.group()
andconsole.groupEnd()
- Use
console.trace()
to show the call stack - Set breakpoints by clicking line numbers in the Sources tab
- Watch expressions by adding them in the Watch panel
Console Tips for React
- Install React Developer Tools for component inspection
- Log component props and state to debug rendering issues
- Use conditional breakpoints for specific scenarios
- Check for React-specific warnings and errors
- Monitor network requests in the Network tab
Debugging Tip:
Use console.log({variableName})
instead of console.log(variableName)
to see both the variable name and value in the console.
Common Memory Problems
- Memory leaks: Resources not being properly released
- High CPU usage: Excessive processing or infinite loops
- Slow performance: Inefficient code or large data structures
- Page crashes: Out of memory errors
- Growing memory usage: Memory increasing over time
Identifying Memory Issues
- Use Chrome DevTools Memory tab to create heap snapshots
- Monitor memory usage in Performance tab
- Look for components that don’t unmount properly
- Check for event listeners that aren’t removed
- Identify large data structures that could be optimized
Fixing Memory Leaks
- Clean up event listeners in
useEffect
return functions - Cancel fetch requests when components unmount
- Unsubscribe from subscriptions (observables, WebSockets)
- Clear intervals and timeouts when no longer needed
- Avoid creating functions inside render that create closures over large data
- Use
useMemo
anduseCallback
to prevent unnecessary recreations
Memory optimization tip:
For large lists, consider implementing virtualization (using libraries like react-window or react-virtualized) to render only visible items instead of the entire list at once.
Common Browser Compatibility Issues
- Different rendering: CSS behaves differently across browsers
- Missing features: Modern JavaScript features not supported in older browsers
- Browser-specific bugs: Issues unique to certain browsers
- Mobile quirks: Problems specific to mobile browsers
- Input handling differences: Form elements behave differently
Ensuring Cross-Browser Compatibility
- Use Babel to transpile modern JavaScript for older browsers
- Include polyfills for missing browser features
- Leverage CSS prefixes or use a tool like Autoprefixer
- Test on multiple browsers (Chrome, Firefox, Safari, Edge)
- Use feature detection instead of browser detection
- Follow web standards and avoid browser-specific hacks
Tools for Browser Compatibility
- caniuse.com: Check feature support across browsers
- BrowserStack: Test on multiple browsers and devices
- Autoprefixer: Automatically add vendor prefixes to CSS
- @babel/preset-env: Target specific browser versions
- core-js: Polyfills for modern JavaScript features
Instead of supporting very old browsers, consider implementing a browser detection system that shows a friendly message to users on unsupported browsers, directing them to upgrade.
Common Causes of Infinite Loops
- Missing dependency array:
useEffect
without dependencies - State updates in render: Calling setState during render phase
- State updates in useEffect: Without proper dependency control
- Mutable references: Modifying objects or arrays directly
- Props changing in parent: Child component updates causing parent re-renders
How to Fix Infinite Loops
- Ensure
useEffect
has a proper dependency array - Use
useCallback
for functions passed as props - Add conditional checks before setting state
- Use functional updates for state based on previous values
- Check for object/array stability with
useMemo
- Use
React.memo
to prevent unnecessary re-renders
Debugging Infinite Loops
- Add console logs to track component renders
- Use React DevTools to profile renders
- Check for “Maximum update depth exceeded” error messages
- Set breakpoints in Chrome DevTools
- Look for rapidly increasing memory usage
Common infinite loop pattern:
useEffect(() => { setData(newData); // This will cause a re-render }, [someValue]); // If someValue changes on every render, you get an infinite loop
Common Responsive Design Challenges
- Layout breaks on mobile: Elements overlap or overflow
- Text scaling issues: Font sizes too large or small on different screens
- Image sizing problems: Images not properly scaling
- Touch targets too small: Buttons or links difficult to tap on mobile
- Content overflow: Content extending beyond viewport
- Media query issues: Breakpoints not working as expected
Responsive Design Best Practices
- Use mobile-first approach (design for mobile, then expand)
- Implement fluid layouts with flexbox and grid
- Use relative units (%, em, rem) instead of fixed pixels
- Set appropriate viewport meta tag
- Test designs across multiple screen sizes
- Use responsive images with proper sizing
- Ensure touch targets are at least 44x44px for mobile
Tailwind CSS for Responsive Design
Tailwind makes responsive design easier with its breakpoint prefixes:
sm:
- small screens (640px and up)md:
- medium screens (768px and up)lg:
- large screens (1024px and up)xl:
- extra large screens (1280px and up)2xl:
- 2x extra large screens (1536px and up)
Example of responsive layout with Tailwind:
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div className="p-4 bg-white rounded shadow">Item 1</div>
<div className="p-4 bg-white rounded shadow">Item 2</div>
<div className="p-4 bg-white rounded shadow">Item 3</div>
</div>
Use Chrome DevTools Device Mode (toggle device toolbar) to quickly test your design on different device sizes and orientations.
Domain Issues
To connect your custom domain to your Lovable app:
- Navigate to Project → Settings → Domains in Lovable
- Click “Add Domain” and enter your domain name
- Update your DNS settings as instructed
- Wait for DNS propagation (can take up to 48 hours)
Custom domain functionality requires a paid Lovable plan.
Example DNS settings for your domain registrar:
# For apex domain (example.com):
Type: A
Name: @
Value: 76.76.21.21
# For www subdomain:
Type: CNAME
Name: www
Value: yourapp.lovable.app
DNS Settings Explanation:
- A Record: Points your root domain to Lovable’s IP address
- CNAME Record: Creates an alias from www to your Lovable app
- TTL (Time-to-Live): Set to 3600 (1 hour) or lower for faster propagation
DNS Verification:
To verify your DNS settings are correct, you can use:
- DNSChecker.org
- MXToolbox
- Command line:
dig example.com
ornslookup example.com
If your custom domain isn’t working:
- Verify DNS settings are configured exactly as specified
- Check if your domain has DNSSEC enabled (might cause issues)
- Use a DNS lookup tool to verify your records have propagated
- Clear your browser cache or try in incognito mode
- Wait at least 24-48 hours for DNS changes to fully propagate
- Ensure your domain is properly verified in the Lovable dashboard
- Check if your domain registrar has extra security features blocking the transfer
Troubleshooting Steps:
- Verify your domain is active and not expired
- Check for conflicting DNS records
- Temporarily disable DNSSEC if you’re having issues
- Ensure no domain forwarding is enabled at your registrar
- Try accessing your site from a different network
Lovable automatically provisions SSL certificates for custom domains. If you’re experiencing SSL issues:
- Ensure your DNS is properly configured
- Check if your domain has CAA records that might restrict certificate issuance
- Wait up to 24 hours for the certificate to be issued
- Verify your browser isn’t caching an old certificate
- Check for certificate transparency logs to see if a certificate was issued
- Contact Lovable support if issues persist
Common SSL Errors:
- ERR_CERT_COMMON_NAME_INVALID: Domain doesn’t match certificate
- ERR_CERT_AUTHORITY_INVALID: Certificate not trusted by browser
- SEC_ERROR_UNKNOWN_ISSUER: Certificate issuer unknown
- SSL_ERROR_BAD_CERT_DOMAIN: Domain doesn’t match certificate
**SSL Security Note: **Lovable uses Let’s Encrypt to provision SSL certificates. These certificates are valid for 90 days and are automatically renewed.
To set up subdomains for your Lovable app:
Option 1: Direct Subdomain Configuration
- Navigate to Project → Settings → Domains
- Click “Add Domain” and enter your subdomain (e.g., app.example.com)
- Add a CNAME record at your DNS provider:
Type: CNAME
Name: app
Value: yourapp.lovable.app
Option 2: Wildcard Subdomain
To support multiple subdomains with one configuration:
Type: CNAME
Name: *
Value: yourapp.lovable.app
Note: Wildcard CNAME records might not be supported by all DNS providers.
Subdomain Best Practices:
- Use consistent naming conventions (app.example.com, api.example.com)
- Consider using subdomains for different environments (staging.example.com)
- Remember each subdomain needs its own SSL certificate, which Lovable handles automatically
To deploy your Lovable app:
- Click the “Publish” button in the top-right corner
- Wait for the build process to complete
- Your app will be available at yourapp.lovable.app
- Review deployment logs for any issues
Deployment Strategies:
- Preview Deployments: Test your app before publishing to production
- Automatic Deployments: Configure your project to deploy automatically on Git changes
- Rollbacks: Revert to previous versions if needed
If your deployment fails:
- Check the deployment logs for specific errors
- Fix any code issues identified in the logs
- Ensure all environment variables are properly set
- Verify all required API keys are valid
- Check for missing dependencies
- Try deploying an earlier working version
- Resolve any build-time errors before deploying again
Common Deployment Errors:
- Module not found: Missing dependency or import
- Build timeout: Build process taking too long
- Memory limit exceeded: Build requires more resources than available
- Environment variable issues: Missing or incorrectly formatted variables
To remove the Lovable badge from your deployed app:
- Go to Project Settings
- Find “Show Lovable Badge” option
- Toggle it off (requires paid plan)
- Redeploy your application
The badge removal option is available on all paid plans. If you don’t see this option, make sure your billing is up to date.
Common Deployment Problems
- Build failures: Check your build command and Node.js version
- 404 errors: Configure redirects for Single Page Applications
- Environment variables: Set them in the hosting platform’s dashboard
- API routes not working: Verify serverless function configuration
- CORS issues: Configure proper headers for API requests
Netlify Configuration
- Create a
netlify.toml
file in your project root - Configure build settings:
npm run build
oryarn build
- Set the publish directory to
dist
for Vite projects - Add redirects for SPA routing
- Configure environment variables in the Netlify dashboard
Vercel Configuration
- Create a
vercel.json
file if needed (often automatic) - Use the Vercel dashboard to configure build settings
- Set environment variables in the Vercel dashboard
- Optionally configure serverless functions
- Domain settings can be managed in the project settings
Troubleshooting Deployment
- Check deployment logs for specific error messages
- Verify that your project builds locally before deploying
- Test with
NODE_ENV=production
locally - Check for case sensitivity issues in imports (critical for Linux servers)
- Ensure all dependencies are properly specified in package.json
- Consider using the hosting provider’s CLI for better debugging
SPA Routing Configuration
For Netlify (netlify.toml
):
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
For Vercel (vercel.json
):
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
Current workaround is user having to add both the domain as well as www. domain counterpart to get the updates to sync.
Supabase issues
- l Scope: Use the principle of least privilege for all credentials
When using Lovable with Supabase, always store sensitive API keys as Supabase Edge Function secrets rather than environment variables or in source code.
Double-check syntax and variable names. See the Supabase docs.
Disconnect and reconnect. Might be caused by an integration update.
Remixing is blocked for Supabase-connected projects for security reasons.
Please report to support.
Usually means a backend server isn’t responding. Use chat mode to debug.
Likely due to invalid credentials. Engineering is working on a fix.
RLS Basics
Row Level Security (RLS) allows you to control which rows users can access in your Supabase tables. Without proper RLS policies:
- Your data may be unprotected and accessible to anyone
- Or users might be unable to access data they should see
If RLS is enabled:
- Define clear access policies.
- Test via Supabase SQL editor.
- Ensure users are authenticated.
Enabling RLS on Tables
How to enable RLS on your Supabase tables:
- Go to the Supabase dashboard and select your project
- Navigate to Table Editor in the left sidebar
- Select the table you want to secure
- Click on Authentication tab
- Toggle Enable RLS to ON
- Create policies to define access rules (without policies, no access is granted)
It’s recommended to enable RLS on all tables from the beginning of your project development.
Common RLS Issues
If you’re experiencing data access problems:
- No Data Returned: RLS might be too restrictive
- Security Concerns: RLS might be too permissive
- Errors When Inserting: Check your INSERT policies
- Auth Issues: Ensure the user is properly authenticated
- Unexpected Access: Anonymous users might have unintended access
Troubleshooting auth.uid() Issues
If your RLS policies using auth.uid() aren’t working as expected:
- User Not Authenticated: Verify that the user is properly signed in
- JWT Token Issues: Check if the JWT token is being correctly passed to Supabase
- Column Type Mismatch: Ensure your user_id column type matches the auth.uid() type (typically UUID)
- Case Sensitivity: UUID comparisons should be case-sensitive
- Incorrect Column Name: Double-check that the column name in your policy matches the database
A common issue is comparing auth.uid() to a user_id stored as text when auth.uid() returns a UUID. Ensure type consistency.
Example RLS Policies
Here are common RLS policy patterns:
-- Allow users to read only their own data
CREATE POLICY "Users can view their own data" ON "profiles"
FOR SELECT
USING (auth.uid() = user_id);
-- Allow authenticated users to insert their own data
CREATE POLICY "Users can insert their own data" ON "profiles"
FOR INSERT
WITH CHECK (auth.uid() = user_id);
-- Allow public access to certain data
CREATE POLICY "Public access to published posts" ON "posts"
FOR SELECT
USING (is_published = true);
Testing RLS Policies
How to verify your RLS policies are working correctly:
- Use the Supabase dashboard to test policies with different roles
- Create test users and verify access patterns
- Log SQL errors from your Lovable app for debugging
- Test both authenticated and anonymous access
Best Practice
Always enable RLS on all tables and explicitly create policies for access patterns. Start with restrictive policies and gradually open them up as needed.
Advanced RLS Techniques
Advanced RLS patterns for Lovable projects
Role-Based Access
Implementing role-based permissions with RLS:
-- Create a view to get user roles
CREATE OR REPLACE FUNCTION get_user_role()
RETURNS TEXT AS $$
SELECT role FROM user_roles WHERE user_id = auth.uid()
$$ LANGUAGE SQL;
-- Policy that checks user role
CREATE POLICY "Admins can do anything" ON "documents"
USING (get_user_role() = 'admin');
Team/Organization Access
Allowing users to access team resources:
-- Allow access to team members
CREATE POLICY "Team members can view" ON "team_documents"
FOR SELECT
USING (
auth.uid() IN (
SELECT user_id FROM team_members
WHERE team_id = team_documents.team_id
)
);
RLS Performance Considerations
Be aware of these performance aspects when using RLS:
- Complex policies can slow down queries
- Joins in policies can be particularly expensive
- Consider indexing columns used in RLS conditions
- For large tables, consider materialized views or other optimizations
Working with Complex Policy Requirements
Solutions for advanced access control scenarios:
- Multiple Conditions: Combine conditions with AND/OR operators
- Hierarchical Access: Use recursive queries or path enumeration patterns
- Temporary Access: Implement time-based conditions (e.g., expiry dates)
- Delegated Permissions: Create sharing mechanisms with junction tables
- Row-Level Ownership Transfer: Consider triggers to maintain ownership history
For very complex access patterns, consider using database functions to encapsulate the logic and make your policies more readable.
Multi-Tenant RLS Strategies
Implementing secure multi-tenant data access:
- Tenant Isolation: Include tenant_id in all tables requiring isolation
- Shared Tables: Define which tables should be shared vs. tenant-specific
- Cross-Tenant Access: Implement explicit sharing mechanisms when needed
- Tenant Hierarchy: Consider parent-child relationships between organizations
- User-Tenant Association: Track which tenants each user belongs to
-- Basic multi-tenant RLS policy
CREATE POLICY "Tenant isolation" ON "tenant_data"
USING (
tenant_id IN (
SELECT tenant_id FROM tenant_members
WHERE user_id = auth.uid()
)
);
Consider using database schemas for complete tenant isolation if your application requires strict separation.
Debugging RLS Issues
Tips for troubleshooting complex RLS problems:
- Temporarily disable RLS to verify it’s the source of the issue
- Add logging to track SQL queries and auth states
- Test simpler policies first, then add complexity
- Verify that auth.uid() is returning the expected values
- Use the Supabase dashboard’s policy tester to validate policies
Common Pitfall
A frequent issue is enabling RLS on a table but forgetting to create any policies. This results in no access to the table’s data, as the default behavior is to deny all access when RLS is enabled.
JWT Claims and Authentication
Using JWT claims for enhanced security
Understanding JWT Claims
JWTs (JSON Web Tokens) contain claims that can be used in RLS policies:
- Standard claims like subject (sub), issuer (iss), expiration (exp)
- Custom claims for roles, permissions, or user attributes
- Claims are verified by Supabase before being used in RLS
Accessing JWT Data in RLS
Examples of accessing JWT claim data in RLS policies:
-- Access the user's ID (UUID)
auth.uid()
-- Check if the user has a specific role
auth.jwt() ->> 'role' = 'admin'
-- Access custom claims
auth.jwt() ->> 'custom_claim' = 'value'
-- Check if user is authenticated at all
auth.role() = 'authenticated'
Working with Custom Claims
Setting and using custom claims in Supabase:
- Create or update claims during authentication or user actions
- Use claims to store frequently needed user data
- Keep claims small to avoid large JWT tokens
- Update claims when relevant user data changes
// Example: Setting custom claims during sign-in
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
options: {
data: {
role: 'admin',
org_id: '123',
permissions: ['read', 'write']
}
}
});
// Accessing those claims in RLS
CREATE POLICY "Admin access" ON "documents"
USING (auth.jwt() ->> 'role' = 'admin');
Custom claims are useful for frequently accessed user attributes but should not replace proper database lookups for complex permissions.
If you’re experiencing data access problems:
- No Data Returned: RLS might be too restrictive
- Security Concerns: RLS might be too permissive
- Errors When Inserting: Check your INSERT policies
- Auth Issues: Ensure the user is properly authenticated
- Unexpected Access: Anonymous users might have unintended access
To connect your Lovable project to Supabase:
- Click the Supabase menu in the top right of the editor
- Select “Connect to Supabase”
- Follow the prompts to connect to your Supabase project
- Once connected, Lovable can see your tables, RLS policies, and functions
If you’re having trouble connecting to Supabase:
- Project Not Found: Verify you’re selecting the correct Supabase project
- Authentication Errors: Ensure you’re logged into the correct Supabase account
- Permission Errors: Check that you have admin/owner access to the Supabase project
- API Keys: Verify your API keys are valid and have not expired
- Connection Timeouts: Try again later or check your network connection
Note: You need to be an owner or administrator of the Supabase project to connect it to Lovable.
Solutions for frequent authentication problems:
- Redirect URL Issues: Ensure all possible domains (including localhost for development) are added to your Supabase project’s allowed redirect URLs
- Session Not Persisting: Check that you’re properly handling the Supabase session storage
- OAuth Provider Errors: Verify provider credentials and callback URLs in Supabase dashboard
- Email Confirmation Not Working: Check spam folders and verify email templates
- JWT Expiration: Implement proper token refresh handling
When deploying your app with a custom domain, remember to add that domain to your Supabase redirect URLs, or authentication flows will fail.
Implementing multi-tenant architecture with Supabase:
- Organization/Team Model: Create tables for organizations and team memberships
- User Assignment: Associate users with organizations through junction tables
- Role-Based Access: Define roles within organizations (admin, member, viewer)
- Data Isolation: Use RLS policies to ensure data separation between tenants
- Shared Resources: Define which data should be shared across tenants
For multi-tenant applications, consider using Supabase’s built-in organization features or implement custom organization tables with proper RLS policies.
Managing file uploads with Supabase Storage:
Setting Up Supabase Storage:
- Go to Supabase Dashboard → Storage
- Create a new bucket (e.g., “avatars”, “documents”)
- Configure access permissions (public or private)
- Set up Row Level Security if needed
Implementing File Uploads:
import { useState } from 'react';
import { supabase } from './supabaseClient';
function FileUploader() {
const [uploading, setUploading] = useState(false);
const [filePath, setFilePath] = useState('');
const [error, setError] = useState('');
async function uploadFile(event) {
try {
setUploading(true);
setError('');
const file = event.target.files[0];
if (!file) return;
// Create a unique file name
const fileExt = file.name.split('.').pop();
const fileName = `${Date.now()}.${fileExt}`;
const filePath = `uploads/${fileName}`;
// Upload the file
const { data, error } = await supabase.storage
.from('documents')
.upload(filePath, file, {
cacheControl: '3600',
upsert: false
});
if (error) throw error;
// Get a public URL for the file
const { data: urlData } = supabase.storage
.from('documents')
.getPublicUrl(filePath);
setFilePath(urlData.publicUrl);
} catch (error) {
setError(error.message);
} finally {
setUploading(false);
}
}
return (
<div className="space-y-4">
{error && <div className="text-red-500">{error}</div>}
<label className="block">
<span className="sr-only">Choose file</span>
<input
type="file"
className="block w-full text-sm text-gray-500
file:mr-4 file:py-2 file:px-4
file:rounded-full file:border-0
file:text-sm file:font-semibold
file:bg-primary file:text-white
hover:file:bg-primary/80"
onChange={uploadFile}
disabled={uploading}
/>
</label>
{uploading && <div>Uploading...</div>}
{filePath && (
<div>
<p>File uploaded successfully!</p>
<a
href={filePath}
target="_blank"
rel="noreferrer"
className="text-blue-500 hover:underline"
>
View uploaded file
</a>
</div>
)}
</div>
);
}
Image Uploads with Preview:
function ImageUploader() {
const [uploading, setUploading] = useState(false);
const [imageUrl, setImageUrl] = useState('');
const [preview, setPreview] = useState('');
// Create a preview when a file is selected
function handleFileChange(event) {
const file = event.target.files[0];
if (!file) return;
// Create a preview URL
const objectUrl = URL.createObjectURL(file);
setPreview(objectUrl);
// Start upload
uploadImage(file);
}
async function uploadImage(file) {
try {
setUploading(true);
// Create a unique file name
const fileExt = file.name.split('.').pop();
const fileName = `${Date.now()}.${fileExt}`;
const filePath = `avatars/${fileName}`;
// Upload the file
const { data, error } = await supabase.storage
.from('avatars')
.upload(filePath, file, {
cacheControl: '3600',
upsert: false
});
if (error) throw error;
// Get a public URL for the file
const { data: urlData } = supabase.storage
.from('avatars')
.getPublicUrl(filePath);
setImageUrl(urlData.publicUrl);
} catch (error) {
console.error('Error uploading image:', error);
} finally {
setUploading(false);
}
}
return (
<div className="space-y-4">
<label className="block">
<span>Upload profile image</span>
<input
type="file"
accept="image/*"
onChange={handleFileChange}
disabled={uploading}
className="mt-1 block"
/>
</label>
{uploading && <div>Uploading...</div>}
{preview && (
<div className="mt-2">
<h4 className="font-medium text-base">Preview:</h4>
<img
src={preview}
alt="Preview"
className="mt-2 h-32 w-32 object-cover rounded-full"
/>
</div>
)}
{imageUrl && (
<div className="mt-2">
<h4 className="font-medium text-base">Uploaded Image:</h4>
<img
src={imageUrl}
alt="Uploaded"
className="mt-2 h-32 w-32 object-cover rounded-full"
/>
</div>
)}
</div>
);
}
Stripe issues
Try a different card or payment method. Contact support if unresolved.
Don’t worry—support can easily fix this.
Go to your settings and cancel via Stripe account.
GitHub issues
You may have deleted your repo. Restore it here.
Branch switching is experimental. Use at your own risk.
Once connected to GitHub, you can work with different branches:
Branch Switching Steps
# To switch from main to dev:
1. In Dev Mode, open the Git panel
2. Select the branch dropdown
3. Choose "dev" or click "Create new branch" if it doesn't exist
4. Your workspace will update to reflect the selected branch
Switching branches will change all files in your workspace to match that branch.
Branch Management:
- Create a new branch: Click “Create new branch” in the Git panel
- Delete a branch: Use the GitHub interface (not available directly in Lovable)
- Default branch: Set in GitHub repository settings
If you can’t switch branches:
- Commit or stash any uncommitted changes
- Check if you have untracked files that would be overwritten
- Try refreshing the Lovable editor
- Check your GitHub permissions.
- Use rollback to undo unwanted changes.
To connect your Lovable project to GitHub:
- Click the GitHub button in the top right of the editor
- Authorize Lovable to access your GitHub account
- Choose whether to create a new repository or use an existing one
- Follow the prompts to complete the connection
Repository Access Levels:
When connecting Lovable to GitHub, you can choose different access levels:
- All repositories: Access to all your GitHub repositories
- Only select repositories: Choose specific repositories to connect
Lovable uses GitHub’s OAuth flow for secure authentication. You can revoke access anytime from your GitHub account settings.
Learn how to commit your changes and follow best practices for Git workflow.
Committing to GitHub
- In Dev Mode, open the Git panel
- Review the changes in the “Changes” tab
- Enter a commit message describing your changes
- Click “Commit” to save your changes
- Click “Push” to send your commits to GitHub
Commit best practices:
- Use clear, descriptive commit messages
- Follow a consistent format (e.g., “feature: add login page”)
- Reference issue numbers when applicable (e.g., “fix #123: correct button alignment”)
- Make small, focused commits rather than large, multi-feature changes
# Good commit messages:
"feat: add user authentication system"
"fix: resolve login error on mobile devices"
"docs: update README with API instructions"
"refactor: simplify payment processing logic"
"chore: update dependencies to latest versions"
When Git can’t automatically merge changes:
- Identify the conflicting files (marked in the Git panel)
- Open each file and look for conflict markers (
<<<<<<<
,=======
, and>>>>>>>
) - Edit the files to resolve conflicts (keep the code you want)
- Remove the conflict markers
- Commit the resolved files
If you’re having trouble with GitHub authentication:
- Reconnect your GitHub account in Lovable
- Check if your GitHub access token has expired
- Verify you have the necessary permissions for the repository
- Ensure two-factor authentication isn’t blocking access
If your push is rejected:
- Pull the latest changes from the remote repository
- Resolve any conflicts
- Try pushing again
- If still failing, check if the branch is protected
In-project issues
Complex multi-step flows can break. Try:
- Breaking steps down
- Validating inputs
- Reviewing logic
- Simulating different user paths
Still stuck? Contact support.
This is an experimental feature. Expect occasional instability.
Need more help?
Still stuck? Try this:
- Use Chat-Only Mode for step-by-step help.
- Submit a bug through our Feedback Portal.
- If you’re a paid customer, contact Support.
Comprehensive Debugging Manual
This document or this website were written by a Lovable power user in our Discord community.
How to use it
- Download it as
Comprehensive_Debugging_Manual.md
. - Upload it to your GitHub project.
- Prompt Lovable: “Read this document. Let me know if it helps. Then create a prompt I should use to troubleshoot this issue.”
- After Lovable responds, say: “Before you proceed, explain in detail why you think this will work. Wait for my approval.”
This ensures deeper understanding before implementing any fix.
Was this page helpful?