import React, { useState } from 'react'; import * as RadixDialog from '@radix-ui/react-dialog'; import { Dialog, DialogTitle, DialogDescription } from '~/components/ui/Dialog'; import { useStore } from '@nanostores/react'; import { netlifyConnection, updateNetlifyConnection } from '~/lib/stores/netlify'; import { vercelConnection } from '~/lib/stores/vercel'; import { useNetlifyDeploy } from './NetlifyDeploy.client'; import { useVercelDeploy } from './VercelDeploy.client'; import { useGitHubDeploy } from './GitHubDeploy.client'; import { GitHubDeploymentDialog } from './GitHubDeploymentDialog'; import { toast } from 'react-toastify'; import { classNames } from '~/utils/classNames'; interface DeployDialogProps { isOpen: boolean; onClose: () => void; } interface DeployProvider { id: 'netlify' | 'vercel' | 'github' | 'cloudflare'; name: string; iconClass: string; iconColor?: string; connected: boolean; comingSoon?: boolean; description: string; features: string[]; } const NetlifyConnectForm: React.FC<{ onSuccess: () => void }> = ({ onSuccess }) => { const [token, setToken] = useState(''); const [isConnecting, setIsConnecting] = useState(false); const handleConnect = async () => { if (!token.trim()) { toast.error('Please enter your Netlify API token'); return; } setIsConnecting(true); try { // Validate token with Netlify API const response = await fetch('https://api.netlify.com/api/v1/user', { headers: { Authorization: `Bearer ${token}`, }, }); if (!response.ok) { throw new Error('Invalid token or authentication failed'); } const userData = (await response.json()) as any; // Update the connection store updateNetlifyConnection({ user: userData, token, }); toast.success(`Connected to Netlify as ${userData.email || userData.name || 'User'}`); onSuccess(); } catch (error) { console.error('Netlify connection error:', error); toast.error('Failed to connect to Netlify. Please check your token.'); } finally { setIsConnecting(false); } }; return (

Connect to Netlify

To deploy your project to Netlify, you need to connect your account using a Personal Access Token.

setToken(e.target.value)} placeholder="Enter your Netlify API token" className={classNames( 'w-full px-3 py-2 rounded-lg text-sm', 'bg-bolt-elements-background-depth-1', 'border border-bolt-elements-borderColor', 'text-bolt-elements-textPrimary placeholder-bolt-elements-textTertiary', 'focus:outline-none focus:ring-2 focus:ring-accent-500 focus:border-transparent', 'disabled:opacity-50', )} disabled={isConnecting} />
Get your token from Netlify

How to get your token:

  1. Go to your Netlify account settings
  2. Navigate to "Applications" → "Personal access tokens"
  3. Click "New access token"
  4. Give it a descriptive name (e.g., "bolt.diy deployment")
  5. Copy the token and paste it here
); }; export const DeployDialog: React.FC = ({ isOpen, onClose }) => { const netlifyConn = useStore(netlifyConnection); const vercelConn = useStore(vercelConnection); const [selectedProvider, setSelectedProvider] = useState<'netlify' | 'vercel' | 'github' | null>(null); const [isDeploying, setIsDeploying] = useState(false); const [showGitHubDialog, setShowGitHubDialog] = useState(false); const [githubFiles, setGithubFiles] = useState | null>(null); const [githubProjectName, setGithubProjectName] = useState(''); const { handleNetlifyDeploy } = useNetlifyDeploy(); const { handleVercelDeploy } = useVercelDeploy(); const { handleGitHubDeploy } = useGitHubDeploy(); const providers: DeployProvider[] = [ { id: 'netlify', name: 'Netlify', iconClass: 'i-simple-icons:netlify', iconColor: 'text-[#00C7B7]', connected: !!netlifyConn.user, description: 'Deploy your site with automatic SSL, global CDN, and continuous deployment', features: [ 'Automatic SSL certificates', 'Global CDN', 'Instant rollbacks', 'Deploy previews', 'Form handling', 'Serverless functions', ], }, { id: 'vercel', name: 'Vercel', iconClass: 'i-simple-icons:vercel', connected: !!vercelConn.user, description: 'Deploy with the platform built for frontend developers', features: [ 'Zero-config deployments', 'Edge Functions', 'Analytics', 'Web Vitals monitoring', 'Preview deployments', 'Automatic HTTPS', ], }, { id: 'github', name: 'GitHub', iconClass: 'i-simple-icons:github', connected: true, // GitHub doesn't require separate auth description: 'Deploy to GitHub Pages or create a repository', features: [ 'Free hosting with GitHub Pages', 'Version control integration', 'Collaborative development', 'Actions & Workflows', 'Issue tracking', 'Pull requests', ], }, { id: 'cloudflare', name: 'Cloudflare Pages', iconClass: 'i-simple-icons:cloudflare', iconColor: 'text-[#F38020]', connected: false, comingSoon: true, description: "Deploy on Cloudflare's global network", features: [ 'Unlimited bandwidth', 'DDoS protection', 'Web Analytics', 'Edge Workers', 'Custom domains', 'Automatic builds', ], }, ]; const handleDeploy = async (provider: 'netlify' | 'vercel' | 'github') => { setIsDeploying(true); try { let success = false; if (provider === 'netlify') { success = await handleNetlifyDeploy(); } else if (provider === 'vercel') { success = await handleVercelDeploy(); } else if (provider === 'github') { const result = await handleGitHubDeploy(); if (result && typeof result === 'object' && result.success && result.files) { setGithubFiles(result.files); setGithubProjectName(result.projectName); setShowGitHubDialog(true); onClose(); return; } success = result && typeof result === 'object' ? result.success : false; } if (success) { toast.success( `Successfully deployed to ${provider === 'netlify' ? 'Netlify' : provider === 'vercel' ? 'Vercel' : 'GitHub'}`, ); onClose(); } } catch (error) { console.error('Deployment error:', error); toast.error( `Failed to deploy to ${provider === 'netlify' ? 'Netlify' : provider === 'vercel' ? 'Vercel' : 'GitHub'}`, ); } finally { setIsDeploying(false); } }; const renderProviderContent = () => { if (!selectedProvider) { return (
{providers.map((provider) => ( ))}
); } const provider = providers.find((p) => p.id === selectedProvider); if (!provider) { return null; } // If provider is not connected, show connection form if (!provider.connected) { if (selectedProvider === 'netlify') { return ( { handleDeploy('netlify'); }} /> ); } // Add Vercel connection form here if needed return
Vercel connection form coming soon...
; } // If connected, show deployment confirmation return (

{provider.name}

Ready to deploy to your {provider.name} account

Connected

Deployment Features:

    {provider.features.map((feature, index) => (
  • {feature}
  • ))}
); }; return ( <> !open && onClose()}>
Deploy Your Project Choose a deployment platform to publish your project to the web
{renderProviderContent()}
{!selectedProvider && (
)}
{/* GitHub Deployment Dialog */} {showGitHubDialog && githubFiles && ( setShowGitHubDialog(false)} projectName={githubProjectName} files={githubFiles} /> )} ); };