Full-screen yearly calendar that shows only all-day events from your Google Calendar. Built with Next.js (App Router), Tailwind CSS, and shadcn-style UI components.
- Install dependencies:
npm install- Create
.envin the project root with:
DATABASE_URL=your-postgresql-database-url
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=replace-with-a-strong-random-string
GOOGLE_CLIENT_ID=your-google-oauth-client-id
GOOGLE_CLIENT_SECRET=your-google-oauth-client-secret
For local development, you can use a local PostgreSQL database or a free hosted option like Neon or Supabase.
-
Configure your Google OAuth app:
- App type: Web application
- Authorized redirect URI:
http://localhost:3000/api/auth/callback/google - Scopes:
openid email profile https://www.googleapis.com/auth/calendar.readonly
-
Run the dev server:
npm run devOpen http://localhost:3000, sign in with Google, and you'll see your all-day events plotted across the full-year view. Use the arrows or Today button to navigate the year.
When deploying to Vercel, you need to configure both your Vercel environment variables and your Google OAuth credentials:
In your Vercel project dashboard, go to Settings → Environment Variables and ensure you have:
NEXTAUTH_URL=https://bigyear.app(or your custom domain)NEXTAUTH_SECRET= a strong random string (generate withopenssl rand -base64 32)GOOGLE_CLIENT_ID= your Google OAuth client IDGOOGLE_CLIENT_SECRET= your Google OAuth client secretDATABASE_URL= your PostgreSQL connection string (seeVERCEL_SETUP.md)
Important: Make sure NEXTAUTH_URL matches your actual Vercel deployment URL exactly (including https://).
In your Google Cloud Console:
- Go to your OAuth 2.0 Client ID
- Under Authorized redirect URIs, add:
https://bigyear.app/api/auth/callback/google(or your custom domain)
- Save the changes
Note: You can have multiple redirect URIs - one for local development (http://localhost:3000/api/auth/callback/google) and one for production.
After updating the environment variables and Google OAuth settings, trigger a new deployment in Vercel (or push a commit) to apply the changes.
If users are seeing a Google security warning that says "Esta aplicación está bloqueada" (This application is blocked), this means Google is blocking access to sensitive scopes. Here's how to fix it:
The most common cause is that your app is still in "Testing" mode. When an app is in testing mode, only users added to the test users list can access it. All other users will see the blocked error.
- Go to Google Cloud Console OAuth consent screen
- Check the Publishing status section at the top
- If it says "Testing", click Publish App
- Confirm the publishing
- Important: After publishing, wait 5-10 minutes for changes to propagate
Make sure your OAuth consent screen is fully configured:
- Go to Google Cloud Console OAuth consent screen
- Verify all required fields are filled:
- App name: Big Year (or your preferred name)
- User support email: Your email address
- Developer contact information: Your email address
- Application home page:
https://bigyear.app - Privacy Policy link:
https://bigyear.app/privacy - Terms of Service link:
https://bigyear.app/terms
- Under Scopes, ensure these are all listed:
openidemailprofilehttps://www.googleapis.com/auth/calendar.readonlyhttps://www.googleapis.com/auth/calendar.events⚠️ This is a sensitive scope
- Check for region restrictions: Scroll down to see if there are any country/region restrictions enabled. If you want global access, make sure no countries are blocked.
- Save all changes
The app requests calendar.events scope, which allows write access to calendars. Google considers this a sensitive scope and requires:
- The app to be published (not in testing mode)
- Proper OAuth consent screen configuration
- Eventually, full verification for complete removal of warnings
- The app will be available to all Google users worldwide
- Users may still see a brief "unverified app" warning, but they can proceed
- For complete removal of warnings, submit for verification (see below)
- Google OAuth doesn't restrict by country/region by default, but unverified apps with sensitive scopes may show different warnings in different regions
- If users in specific countries are blocked, check the OAuth consent screen for any country restrictions
- The error message language (e.g., Spanish "Esta aplicación está bloqueada") reflects the user's Google account language preference, not a regional restriction
- Publishing the app and completing verification ensures access for users worldwide
To remove the Google "unverified app" warning screens, you need to configure your OAuth consent screen and optionally submit your app for verification:
- Go to Google Cloud Console
- Select your OAuth 2.0 Client ID project
- Fill out the OAuth consent screen:
- User Type: Choose "External" (unless you have a Google Workspace)
- App name: Big Year (or your preferred name)
- User support email: gabe@valdivia.works (your email)
- Developer contact information: gabe@valdivia.works
- App domain (optional): bigyear.app
- Authorized domains: Add
bigyear.app(or your custom domain) - Application home page:
https://bigyear.app - Privacy Policy link:
https://bigyear.app/privacy - Terms of Service link:
https://bigyear.app/terms
- Under Scopes, add:
openidemailprofilehttps://www.googleapis.com/auth/calendar.readonlyhttps://www.googleapis.com/auth/calendar.events
- Save and continue
After configuring the consent screen:
- Go to the Publishing status section
- Click Publish App
- Confirm the publishing
Note: Publishing makes your app available to all Google users. The "unverified app" warnings will be significantly reduced, though some users may still see a brief warning if you haven't completed full verification.
For complete removal of warnings and a verified badge:
- Go to Google Cloud Console OAuth consent screen
- Click Submit for verification
- Complete the verification form with:
- Detailed explanation of why you need each scope
- Video demonstration of your app
- Privacy policy and terms of service (already created above)
- Wait for Google's review (can take several weeks)
Important: The privacy policy and terms pages are already created at /privacy and /terms. Make sure your app is deployed so these URLs are accessible before submitting for verification.
If you see an error in Google Cloud Console that says "The website of your home page URL 'https://bigyear.app' is not registered to you", you need to verify domain ownership.
- Go to Google Cloud Console OAuth consent screen
- Scroll down to the App domain section
- Under Authorized domains, make sure
bigyear.appis listed - If it's not there, click + ADD DOMAIN and add
bigyear.app - Save the changes
Google needs to verify that you own the domain. There are two main methods:
How to Verify Domain Ownership:
The "Learn more" link in the modal takes you to documentation, not the verification interface. To actually verify domain ownership, you need to use Google Search Console. Here's how:
Most Likely Solution: Verify Domain in Google Search Console
Google often requires domain verification through Search Console before it can be used in OAuth. To get the HTML file upload option:
- Go to Google Search Console
- Click "Add property" or use the property selector at the top
- Important: Select "URL prefix" (not "Domain") to get HTML file upload option
- Enter:
https://bigyear.app - Click "Continue"
- You'll see verification method options - choose "HTML file upload"
- Google will provide:
- A filename like
google1234567890.html - HTML content to put in that file
- A filename like
- Create the file in your project's
publicfolder (see steps below) - Deploy to Vercel
- Go back to Search Console and click "Verify"
- Once verified in Search Console, return to the OAuth consent screen Branding page - the domain should now be recognized and the verification issue should be resolved
Note: If you already selected "Domain" and see DNS verification, you can either:
- Use the DNS method (add the TXT record to your domain's DNS settings), OR
- Remove that property and add a new one using "URL prefix" to get the HTML file upload option
Alternative: Try Verification Center
- Close the modal
- Click on "Verification Center" in the left sidebar (under Google Auth Platform)
- This should show you all verification requirements and issues
- Look for domain verification options there
If you don't see the verification option:
- Make sure you've saved the domain in the Authorized domains section first
- Try refreshing the page
- The verification option may appear after a few minutes
- Look for a "Verify ownership" or "Verify domain" button/link
After selecting HTML file upload:
- Google will show you the filename and HTML content
- Copy both the filename and the HTML content
- In your project:
- Create a
publicfolder in your project root (if it doesn't exist) - Create the file
public/google1234567890.html(use the exact filename Google provides) - Paste the exact HTML content Google provides into that file
- Create a
- Deploy to Vercel
- The file will be accessible at
https://bigyear.app/google1234567890.html - Go back to Google Cloud Console and click Verify or Test to verify the file is accessible
- Once verified, the domain ownership status will update
Alternative Method - Using Route Handler:
If you prefer using a route handler instead of the public folder:
- Create
app/google[your-verification-code]/route.ts(replace[your-verification-code]with the actual code) - Use this template:
import { NextResponse } from "next/server";
export async function GET() {
return new NextResponse(
'<meta name="google-site-verification" content="YOUR_CONTENT_HERE" />',
{
headers: { "Content-Type": "text/html" },
}
);
}- Replace
YOUR_CONTENT_HEREwith the exact HTML content Google provides - Add a rewrite in
next.config.mjsto map/google[code].htmlto/google[code] - Deploy and verify
- In Google Cloud Console, select the DNS verification method
- Google will provide a TXT record to add to your DNS
- Add the TXT record to your domain's DNS settings (wherever you manage DNS for
bigyear.app) - Wait for DNS propagation (can take a few minutes to 48 hours)
- Click Verify in Google Cloud Console
Once verified:
- The branding verification issue should be resolved
- You can proceed with app verification if needed
- The domain will be marked as verified in Google Cloud Console
Note: If you're using Vercel, the HTML file method is usually easier since you can create a route to serve the verification file directly.
If you see security alerts in Google Cloud Console's "Project Checkup", here's how to fix them:
NextAuth automatically uses PKCE for secure OAuth flows. To ensure it's working correctly:
- Go to APIs & Services → Credentials
- Click on your OAuth 2.0 Client ID ("Big Year Calendar")
- Verify Application type is set to "Web application" (not "Desktop app" or "Other")
- Ensure Authorized redirect URIs are properly configured with HTTPS URLs
- Save any changes
Note: If the alert persists, it may take 24-48 hours for Google's systems to recognize the secure flow configuration.
To enable incremental authorization support:
- Go to APIs & Services → Credentials
- Click on your OAuth 2.0 Client ID
- Look for Advanced settings or scroll down to find configuration options
- Some OAuth clients automatically support incremental authorization when configured as "Web application" type
- If there's an explicit option to enable it, turn it on
Alternative: If incremental authorization isn't available or applicable (since this app needs all scopes from the start), you can:
- Click "Learn how to fix it" in the Project Checkup alert for specific guidance
- The alert may be informational rather than critical if your app legitimately needs all scopes upfront
To enable Cross-Account Protection:
- Go to APIs & Services → OAuth consent screen
- Scroll down to find Advanced settings or look for Security section
- Enable Cross-Account Protection
- This feature helps prevent unauthorized access when users have multiple Google accounts
- Save the changes
Note: Cross-Account Protection is a security feature that Google recommends for production apps.
After making these changes:
- Wait 24-48 hours for changes to propagate through Google's systems
- Go back to Project Checkup
- Refresh the page to see updated status
- Some alerts may require additional configuration or may be informational
Important: The "Send token securely" and "WebViews usage" alerts showing green checkmarks indicate those security measures are already correctly configured.
- Only all-day events are fetched: events with
start.date(notstart.dateTime) are included. - Access tokens are automatically refreshed using the Google refresh token.
- The calendar auto-fills the entire viewport (full width and height).