A complete MERN Stack application demonstrating dynamic form building with Airtable integration, OAuth authentication, conditional logic, and file uploads.
- ✅ Airtable OAuth 2.0 integration
- ✅ JWT token-based authentication
- ✅ Secure session management
- ✅ Protected routes and API endpoints
- ✅ Connect to any Airtable base and table
- ✅ Auto-detect field types and options
- ✅ Drag-and-drop field ordering
- ✅ Real-time form preview
- ✅ Custom field labels and validation
- ✅ Show/hide fields based on other field values
- ✅ Multiple condition types (equals, contains, etc.)
- ✅ Real-time form logic evaluation
- ✅ Complex dependency chains
- ✅ Multiple file uploads
- ✅ File type validation
- ✅ Direct upload to Airtable attachments
- ✅ Image and document support
- ✅ Real-time data fetching from Airtable
- ✅ Live form submission tracking
- ✅ Data visualization and export
- ✅ Bidirectional sync with Airtable
- ✅ Modern responsive design
- ✅ CSS modules with TypeScript
- ✅ Professional design system
- ✅ Accessibility features
- Node.js (v20.17.0 or higher)
- MongoDB (local or cloud instance)
- Airtable account and OAuth app
git clone <repository-url>
cd airtable-form-buildercd backend
npm installCreate a .env file in the backend directory:
MONGODB_URI=mongodb://localhost:27017/airtable-form-builder
PORT=5000
JWT_SECRET=your-jwt-secret-key
SESSION_SECRET=your-session-secret-key
# Airtable OAuth Configuration
AIRTABLE_CLIENT_ID=your-airtable-client-id
AIRTABLE_CLIENT_SECRET=your-airtable-client-secret
AIRTABLE_REDIRECT_URI=http://localhost:5000/auth/airtable/callback
# Frontend URL
FRONTEND_URL=http://localhost:5173Start the backend server:
npm run devcd frontend
npm installStart the frontend development server:
npm run dev-
Create Airtable OAuth App:
- Go to Airtable Developer Portal
- Click "Create new app"
- Choose "OAuth integration"
-
Configure OAuth Settings:
- App name: Your app name
- Redirect URLs:
http://localhost:5000/auth/airtable/callback - Scopes:
data.records:readdata.records:writedata.schema:read
-
Get Credentials:
- Copy the Client ID and Client Secret
- Add them to your backend
.envfile
-
Test OAuth Flow:
- Start both backend and frontend servers
- Navigate to
http://localhost:5173 - Click "Login with Airtable"
backend/
├── models/
│ ├── User.js # User model with Airtable tokens
│ └── Form.js # Form configuration model
├── routes/
│ ├── auth.js # OAuth authentication routes
│ ├── airtable.js # Airtable API integration
│ └── forms.js # Form CRUD operations
├── middleware/
│ └── auth.js # JWT authentication middleware
└── server.js # Express server setup
frontend/src/
├── components/ # Reusable UI components
├── pages/
│ ├── Login.tsx # OAuth login page
│ ├── Dashboard.tsx # Form management dashboard
│ ├── FormBuilder.tsx # Form creation/editing
│ └── FormViewer.tsx # Public form filling
├── contexts/
│ └── AuthContext.tsx # Authentication state management
├── services/
│ └── api.ts # API service layer
└── types/
└── index.ts # TypeScript type definitions
GET /auth/airtable- Initiate OAuth flowGET /auth/airtable/callback- OAuth callbackGET /auth/me- Get current userPOST /auth/logout- Logout user
GET /api/airtable/bases- Get user's basesGET /api/airtable/bases/:baseId/tables- Get base tablesGET /api/airtable/bases/:baseId/tables/:tableId/fields- Get table fieldsPOST /api/airtable/bases/:baseId/tables/:tableId/records- Create record
POST /api/forms- Create formGET /api/forms- Get user's formsGET /api/forms/:id- Get specific formPUT /api/forms/:id- Update formDELETE /api/forms/:id- Delete form
The application supports conditional field visibility based on previous answers:
- equals: Show field if previous answer equals specific value
- not_equals: Show field if previous answer doesn't equal value
- contains: Show field if previous answer contains text
- not_contains: Show field if previous answer doesn't contain text
{
dependsOnField: "field_role",
condition: "equals",
value: "Engineer"
}This will show the field only when the "Role" field equals "Engineer".
- Select Base & Table: Choose which Airtable base and table to connect
- Add Fields: Click on available fields to add them to your form
- Customize Questions: Rename field labels and mark as required
- Apply Logic: Set conditional visibility rules (optional)
- Save Form: Form is ready for sharing and collecting responses
- Dynamic Rendering: Form fields appear/hide based on conditional logic
- Validation: Required fields are validated before submission
- Airtable Integration: Responses are automatically saved as new records
- Field Mapping: Form fields map back to original Airtable field names
Terminal 1 (Backend):
cd backend
npm run devTerminal 2 (Frontend):
cd frontend
npm run devBackend:
cd backend
npm startFrontend:
cd frontend
npm run build
npm run previewClean OAuth login interface with Airtable branding.
Overview of all created forms with management options.
Drag-and-drop interface for building forms from Airtable fields.
Clean, responsive form interface for end users.
- OAuth Error: Verify redirect URL matches exactly in Airtable app settings
- MongoDB Connection: Ensure MongoDB is running and connection string is correct
- CORS Issues: Check frontend URL is whitelisted in backend CORS settings
- Field Types: Only supported Airtable field types will appear in form builder
Set NODE_ENV=development for detailed error logging.
MIT License - see LICENSE file for details.
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request