https://github.com/rafactx/nextjs-testimonial-form
Production-ready testimonial form with chat UI, Google Sheets integration, and modern stack (Next.js 16, React 19, TypeScript, Biome)
https://github.com/rafactx/nextjs-testimonial-form
biome chat-interface form google-sheets nextjs react shadcn-ui tailwindcss testimonials typescript
Last synced: 7 days ago
JSON representation
Production-ready testimonial form with chat UI, Google Sheets integration, and modern stack (Next.js 16, React 19, TypeScript, Biome)
- Host: GitHub
- URL: https://github.com/rafactx/nextjs-testimonial-form
- Owner: rafactx
- License: mit
- Created: 2025-12-27T15:07:59.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2025-12-27T16:23:01.000Z (4 months ago)
- Last Synced: 2025-12-29T12:13:39.510Z (4 months ago)
- Topics: biome, chat-interface, form, google-sheets, nextjs, react, shadcn-ui, tailwindcss, testimonials, typescript
- Language: TypeScript
- Homepage: https://depoimentodavince.vercel.app
- Size: 434 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# Next.js Testimonial Form
**Production-ready testimonial collection with Google Sheets integration**
[](https://github.com/rafactx/nextjs-testimonial-form/actions/workflows/ci.yml)
[](https://nextjs.org/)
[](https://www.typescriptlang.org/)
[](https://biomejs.dev/)
[](./LICENSE)
[Features](#features) β’ [Quick Start](#quick-start) β’ [CI/CD](#cicd-setup) β’ [Deployment](#deployment)
---
## About
Conversational testimonial form built with Next.js 16 App Router, featuring chat-style UI with typing animations. Data syncs automatically to Google Sheets.
Originally created for [Davince Band](https://davince.com.br), fully customizable for any testimonial collection use case.
**Live Demo**: [Coming soon]
### Key Highlights
- π **Modern Stack** - Next.js 16, React 19, TypeScript, Tailwind CSS 4, Biome
- π¬ **Chat Interface** - Conversational flow with realistic typing animations
- β‘ **Performance** - Memoized components, debounced scrolling, optimized re-renders
- π **Google Sheets** - Automatic data sync, no database required
- π **Secure** - Environment validation, CSP headers, server-side credentials
- π¨ **Themeable** - Dark mode, customizable design tokens
- π± **Responsive** - Mobile-first design, optimized for all screen sizes
- βΏ **Accessible** - WCAG compliant, keyboard navigation
## Features
**User Experience**
- Multi-step chat flow with typing animations
- Character count (250 limit) with live feedback
- Optional internal feedback field (not published)
- Review screen with inline editing
- Responsive layout optimized for mobile and desktop
- Comprehensive loading & error states
**Technical**
- Server-side Google Sheets API integration
- Build-time environment validation
- Type-safe error handling with custom error classes
- Optimized image formats (AVIF/WebP)
- Security headers (CSP, X-Frame-Options, HSTS)
- Pre-commit hooks with Husky + lint-staged
## Quick Start
**Prerequisites**: [Bun](https://bun.sh/) β₯1.0 or Node.js β₯24
```bash
# Clone & install
git clone https://github.com/rafactx/nextjs-testimonial-form.git
cd nextjs-testimonial-form
bun install
# Configure environment
cp .env.local.example .env.local
# Edit .env.local with your Google Sheets credentials
# Start dev server
bun dev
```
Open [http://localhost:3000](http://localhost:3000)
### Google Sheets Setup
Complete configuration guide
#### 1. Create Service Account
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
2. Create project β **APIs & Services** β **Credentials**
3. **Create Credentials** β **Service Account**
4. Complete form β **Create** β Skip permissions β **Done**
#### 2. Generate JSON Key
1. Select service account β **Keys** tab
2. **Add Key** β **Create new key** β **JSON**
3. Download and store securely (never commit to git)
#### 3. Enable API
1. **APIs & Services** β **Library**
2. Search "Google Sheets API" β **Enable**
#### 4. Configure Spreadsheet
1. Create new Google Sheet
2. Share with service account email (from JSON) as **Editor**
3. Copy spreadsheet ID from URL: `docs.google.com/spreadsheets/d/{ID}/edit`
#### 5. Environment Variables
Map JSON values to `.env.local`:
```env
GOOGLE_SHEETS_CLIENT_EMAIL=your-account@project.iam.gserviceaccount.com
GOOGLE_SHEETS_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYour_Key\n-----END PRIVATE KEY-----\n"
GOOGLE_SHEETS_SPREADSHEET_ID=your-spreadsheet-id
GOOGLE_SHEETS_SHEET_NAME=Sheet1
```
β οΈ **Important**: Keep `\n` in `PRIVATE_KEY` (they're line breaks, not literal text)
## CI/CD Setup
### GitHub Actions
The repository includes a CI workflow ([.github/workflows/ci.yml](.github/workflows/ci.yml)) that runs on push/PR:
1. **Lint & Check** - Biome linting, formatting, and type checking
2. **Build** - Next.js production build with mock env vars
**No secrets needed for CI** - build uses mock values to validate env var existence.
### Configuring Secrets (for deployment)
For production deployments on Vercel/other platforms:
1. **GitHub Environments** (recommended for security):
- Settings β Environments β **New environment** (e.g., "Production")
- Add secrets:
- `GOOGLE_SHEETS_CLIENT_EMAIL`
- `GOOGLE_SHEETS_PRIVATE_KEY`
- `GOOGLE_SHEETS_SPREADSHEET_ID`
- `GOOGLE_SHEETS_SHEET_NAME`
- Configure **Required reviewers** for approval gate
- Enable **Branch protection** on `main`
2. **Vercel Integration**:
- Link GitHub repo to Vercel project
- Add environment variables in Vercel dashboard
- Auto-deploy on push to `main`
## Scripts
```bash
# Development
bun dev # Start dev server with hot reload
bun build # Production build
bun start # Production server
# Code Quality
bun lint # Run Biome linter
bun lint:fix # Auto-fix Biome issues
bun format # Format code with Biome
bun format:check # Verify formatting
bun check # Lint + format + fix (pre-commit)
bun ci # CI mode (strict, no fixes)
```
## Deployment
### Vercel (Recommended)
[](https://vercel.com/new/clone?repository-url=https://github.com/rafactx/nextjs-testimonial-form)
**Steps**:
1. Import repository on [vercel.com](https://vercel.com)
2. Add environment variables (see [Google Sheets Setup](#google-sheets-setup))
3. Deploy
**CLI**:
```bash
bun add -g vercel
vercel login
vercel --prod
```
### Other Platforms
Works with any Next.js-supporting platform:
- **Netlify** - Use Next.js Runtime plugin
- **Railway** - Auto-deploy from Git
- **Render** - Connect repository
- **AWS Amplify** - Git-based deployment
## Architecture
```
testimonial-form/
βββ app/ # Next.js App Router
β βββ api/testimonials/ # Submission endpoint (POST)
β βββ layout.tsx # Root layout + ThemeProvider
β βββ page.tsx # Main page
βββ components/
β βββ ui/ # Base components (shadcn/ui)
β βββ testimonial-form.tsx # Main form (585 lines)
βββ lib/
β βββ env.ts # Build-time validation
β βββ errors.ts # Type-safe error classes
β βββ google-sheets.ts # Sheets API client
β βββ utils.ts # Utilities (cn helper)
βββ .github/workflows/ # CI pipeline
```
## Troubleshooting
### Build Errors
**`VariΓ‘veis de ambiente faltando`**
- **Cause**: Missing required env vars
- **Fix**: Verify `.env.local` has all 4 variables from [Google Sheets Setup](#google-sheets-setup)
- **CI**: Use mock values (already configured in [ci.yml](.github/workflows/ci.yml))
**`Error: Could not load the default credentials`**
- **Cause**: Invalid service account credentials
- **Fix**: Re-download JSON key, verify `PRIVATE_KEY` includes `\n` characters
### Runtime Errors
**`API Request failed with status 403`**
- **Cause**: Service account lacks spreadsheet access
- **Fix**: Share spreadsheet with service account email as Editor
**`Error: Unable to parse range`**
- **Cause**: `SHEET_NAME` doesn't match actual sheet name
- **Fix**: Check sheet tab name in Google Sheets (default: "Sheet1")
### Development Issues
**Pre-commit hook not running**
- **Fix**: `chmod +x .husky/pre-commit && git add .husky/pre-commit`
**Biome errors on CSS files**
- **Expected**: Biome skips CSS (Tailwind not supported), only lints TS/JS/JSON
**Port 3000 already in use**
- **Fix**: `lsof -ti:3000 | xargs kill -9` or change port: `bun dev -- -p 3001`
## Customization
### Theme
Modify design tokens in [app/globals.css](app/globals.css):
```css
@theme inline {
--color-primary: #3b82f6;
--color-secondary: #8b5cf6;
/* Add custom colors */
}
```
### Messages
Edit conversation flow in [components/testimonial-form.tsx](components/testimonial-form.tsx):
```tsx
const botMessages: Record = useMemo(() => ({
name: ["Custom greeting!", "What's your name?"],
testimonial: ["Tell us about your experience..."],
// ...
}), [])
```
### Data Schema
Testimonials saved to Google Sheets:
| Timestamp | Name | Testimonial | Internal Feedback |
|-----------|------|-------------|-------------------|
| 2025-12-27 10:30 | John Doe | Amazing! | Feature request X |
## Performance
**Optimizations**:
- Component memoization (`React.memo`)
- Callback stabilization (`useCallback`)
- Derived state memoization (`useMemo`)
- Debounced scroll (100ms timeout)
- Next.js Image (AVIF/WebP with blur placeholder)
- Tree-shaking (optimized imports)
- Gzip/Brotli compression
**Metrics** (estimated):
- First Contentful Paint: < 1.5s
- Time to Interactive: < 3.5s
- Cumulative Layout Shift: < 0.1
## Contributing
See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
**Quick start**:
1. Fork repository
2. Create feature branch: `git checkout -b feature/name`
3. Make changes + add Biome checks pass
4. Commit with [Conventional Commits](https://www.conventionalcommits.org/)
5. Push and open PR
## License
MIT License - see [LICENSE](./LICENSE)
## Acknowledgments
- [Next.js](https://nextjs.org/) - React framework
- [Biome](https://biomejs.dev/) - Fast linter & formatter
- [shadcn/ui](https://ui.shadcn.com/) - Component system
- [react-type-animation](https://react-type-animation.netlify.app/) - Typing effects
- [Google Sheets API](https://developers.google.com/sheets/api) - Data storage
---