This document describes the implementation of Cloudflare Pages Functions in the EnergiWatch-MVP project to securely handle API calls to the Gemini API without exposing the API key to clients.
The implementation follows a secure proxy pattern:
- Frontend code sends requests to a Pages Function endpoint
- Pages Function securely accesses the API key from Cloudflare Environment Variables
- Pages Function forwards the request to the Gemini API with the secure key
- Response is returned to the frontend
┌─────────────┐ ┌───────────────────┐ ┌────────────┐
│ │ │ │ │ │
│ Frontend │────▶│ Pages Function │────▶│ Gemini │
│ │ │ │ │ API │
│ │◀────│ │◀────│ │
└─────────────┘ └───────────────────┘ └────────────┘
│
▼
┌─────────────────┐
│ │
│ Cloudflare │
│ Environment │
│ Variables │
└─────────────────┘
The Pages Function is implemented as a serverless function that:
- Accepts POST requests with a prompt and optional model parameter
- Retrieves the API key from Cloudflare Environment Variables
- Forwards the request to the Gemini API
- Returns the response to the client
Key features:
- Default model fallback if none is specified
- Proper error handling
- HTTP method restrictions
- JSON parsing and validation
The frontend code has been refactored to:
- Use the Pages Function endpoint instead of direct API calls
- Implement flexible model selection with a
GEMINI_MODELSobject - Remove direct API key usage from frontend code
- Add proper error handling for API calls
The following configuration changes were made:
- Added
[functions]configuration towrangler.toml - Updated
package.jsonscripts for local development and deployment - Added Environment Variables configuration for API key access
To run the application locally with Pages Functions:
npm run dev:cfThis will:
- Build the frontend assets
- Start a local Cloudflare Pages development server
- Serve both static assets and Pages Functions
- Use the API key from your local environment variables
To deploy the application to Cloudflare Pages:
npm run deploy:cfAlternatively, you can deploy through the Cloudflare dashboard if you encounter API token permission issues.
This implementation provides several security benefits:
- API Key Protection: The API key is never exposed in frontend code or browser
- Controlled Access: All API calls are proxied through the serverless function
- Error Handling: Proper error handling prevents sensitive information leakage
- Method Restrictions: Only POST requests are allowed to the function endpoint
To add new Gemini models:
- Add the model to the
GEMINI_MODELSobject inaiService.js - Use the new model by passing it to the
callGemini()function
If the Gemini API changes:
- Update the request format in the Pages Function
- Update the response parsing in both the function and frontend code
Common issues:
- API Key Access: Ensure the API key is properly set in Cloudflare Environment Variables
- Function Errors: Check Cloudflare Pages logs for function execution errors
- Local Development: Ensure environment variables are properly set for local testing
We encountered a 500 Internal Server Error when calling the Gemini API through our Pages Function. The error message was: Gemini API error: API error: Gemini API error.
The issue was caused by two main factors:
- Initial Model Issues: Initial attempts with models like
gemini-2.5-flash-previewandgemini-2.0-pro(user's original preference) resulted in errors. During troubleshooting,gemini-2.0-flashwas also temporarily suspected or misconfigured, leading to exploration of other models likegemini-pro. - Outdated API Endpoint: We were using an older API endpoint (e.g.,
v2beta) which might have contributed to issues or lacked support for all desired models.
We made the following changes to resolve the integration:
- Confirmed Available Models: Used a script (
list-gemini-models.js) to verify models accessible with the API key. - Established Model Prioritization:
- Set
gemini-2.0-flashas the primary model for both client-side requests and server-side attempts, as it was confirmed to be working reliably. - Implemented server-side fallbacks to
gemini-1.5-proand thengemini-proif the primary model fails.
- Set
- Updated API Endpoint: Switched to the stable
v1API endpoint. - Improved API Key Access: Ensured robust API key retrieval in the Pages Function.
- Enhanced Logging & Error Handling: Added comprehensive logging and more detailed error messages for easier debugging.
It's important to note that our implementation uses Cloudflare Environment Variables (set in the Cloudflare Pages dashboard under "Variables and Secrets") rather than the separate Cloudflare Secret Store feature.
While our documentation mentions the "Secret Store", we're actually using:
- Environment Variables in the Cloudflare dashboard (with the "Encrypt" option enabled)
- Bindings in
wrangler.tomlto make these variables available to our Pages Function
The Cloudflare Secret Store is a separate feature that allows sharing secrets across multiple Workers/applications and is not currently used in this project.