Implement GitHub Pages deployment with serverless forms and fix image loading issues#232
Conversation
…d image path fixes Co-authored-by: syed-reza98 <71028588+syed-reza98@users.noreply.github.com>
Co-authored-by: syed-reza98 <71028588+syed-reza98@users.noreply.github.com>
| export function isStaticMode(): boolean { | ||
| if (typeof window === 'undefined') return false; | ||
| // Check if API routes are available by testing environment | ||
| const isGitHubPages = window.location.hostname.includes('github.io'); |
Check failure
Code scanning / CodeQL
Incomplete URL substring sanitization High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 months ago
To properly determine if the current hostname is actually a GitHub Pages domain, we should explicitly check for exact whitelisted domain names. For GitHub Pages, the domain is normally <username>.github.io. We should check that the hostname matches either github.io or ends with .github.io but not with additional characters afterward. This can be done by testing for a hostname pattern using string methods, or better, with a regular expression, or parsing with the URL API. The fix is to replace the substring check in line 43 with a check that window.location.hostname ends exactly with .github.io or is equal to github.io. This ensures only intended hostnames match and malicious hostnames such as github.io.evil.com or mygithub.io.example.com do not match. No extraneous imports are needed, as JavaScript string methods suffice for this fix.
| @@ -40,7 +40,8 @@ | ||
| export function isStaticMode(): boolean { | ||
| if (typeof window === 'undefined') return false; | ||
| // Check if API routes are available by testing environment | ||
| const isGitHubPages = window.location.hostname.includes('github.io'); | ||
| const hostname = window.location.hostname; | ||
| const isGitHubPages = hostname === 'github.io' || hostname.endsWith('.github.io'); | ||
| return isGitHubPages || !process.env.NEXT_PUBLIC_API_AVAILABLE; | ||
| } | ||
|
|
Co-authored-by: syed-reza98 <71028588+syed-reza98@users.noreply.github.com>
Co-authored-by: syed-reza98 <71028588+syed-reza98@users.noreply.github.com>
|
@copilot Web3forms signup with codestromhub@gmail.com The repository secret has been updated NEXT_PUBLIC_WEB3FORMS_KEY for Web3forms access key All the emails sent from codestromhub@gmail.com and in cc add the mail arvincia@sparrow-group.com |
…th CC to arvincia@sparrow-group.com Co-authored-by: syed-reza98 <71028588+syed-reza98@users.noreply.github.com>
Updated Web3Forms configuration as requested: ✅ Email from: codestromhub@gmail.com All documentation updated to reflect the new email setup. The changes ensure all form submissions are sent from codestromhub@gmail.com with arvincia@sparrow-group.com in CC. Commit: This update |
There was a problem hiding this comment.
Pull Request Overview
This PR implements a comprehensive GitHub Pages deployment solution for a Next.js wedding website by addressing fundamental limitations of static hosting. The solution transforms a full-stack application into a hybrid architecture that works seamlessly in both static (GitHub Pages) and server environments through intelligent environment detection and serverless form handling.
Key changes include:
- Fixed image loading issues by implementing basePath-aware asset URLs
- Replaced API-dependent forms with serverless Web3Forms integration
- Created dual-mode architecture that automatically detects deployment environment
Reviewed Changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| client/src/lib/utils.ts | Added assetUrl() and getBasePath() helper functions for basePath-aware asset loading |
| client/src/lib/serverless-forms.ts | New serverless form submission handler with Web3Forms integration and environment detection |
| client/src/components/HeartCollage.tsx | Updated default image props to use assetUrl() helper |
| client/src/app/rsvp/page.tsx | Integrated serverless form submission replacing direct API calls |
| client/src/app/page.tsx | Fixed 17 image paths to use assetUrl() helper for proper basePath handling |
| client/src/app/events/page.tsx | Updated dynamic image paths to use assetUrl() helper |
| client/src/app/contact/page.tsx | Integrated serverless form submission replacing direct API calls |
| client/next.config.ts | Enhanced GitHub Pages configuration with proper environment detection |
| README.md | Updated deployment section with comprehensive GitHub Pages and server deployment options |
| QUICK_DEPLOY.md | New 3-step deployment guide with testing checklist and troubleshooting |
| IMPLEMENTATION_SUMMARY.md | Comprehensive technical implementation details and architecture explanation |
| GITHUB_PAGES_SETUP.md | Complete setup guide with Web3Forms configuration and maintenance instructions |
| DEPLOYMENT_READY.md | Quick start guide covering problems solved and next steps |
| CHANGES_SUMMARY.md | Visual guide of all modifications with flow diagrams and statistics |
| .github/workflows/nextjs.yml | Added GITHUB_PAGES environment variable and Web3Forms placeholder |
| coupleImage = assetUrl('/images/heart/couple.jpeg'), | ||
| cakeImage = assetUrl('/images/heart/cake.jpeg') | ||
| }) => { |
There was a problem hiding this comment.
Default parameter values cannot use function calls during component definition. The assetUrl() function should be called inside the component body or use static values as defaults.
| coupleImage = assetUrl('/images/heart/couple.jpeg'), | |
| cakeImage = assetUrl('/images/heart/cake.jpeg') | |
| }) => { | |
| coupleImage, | |
| cakeImage | |
| }) => { | |
| const resolvedCoupleImage = coupleImage ?? assetUrl('/images/heart/couple.jpeg'); | |
| const resolvedCakeImage = cakeImage ?? assetUrl('/images/heart/cake.jpeg'); |
| try { | ||
| // Web3Forms access key - can be public, it's rate-limited per domain | ||
| // Get your free key at https://web3forms.com | ||
| const accessKey = process.env.NEXT_PUBLIC_WEB3FORMS_KEY || 'YOUR_WEB3FORMS_ACCESS_KEY_HERE'; |
There was a problem hiding this comment.
Using a placeholder string as fallback for the access key could lead to silent failures in production. Consider throwing an error or using an empty string to make missing configuration more obvious.
| const accessKey = process.env.NEXT_PUBLIC_WEB3FORMS_KEY || 'YOUR_WEB3FORMS_ACCESS_KEY_HERE'; | |
| const accessKey = process.env.NEXT_PUBLIC_WEB3FORMS_KEY; | |
| if (!accessKey) { | |
| throw new Error('Web3Forms access key is missing. Please set NEXT_PUBLIC_WEB3FORMS_KEY in your environment.'); | |
| } |
| export function isStaticMode(): boolean { | ||
| if (typeof window === 'undefined') return false; | ||
| // Check if API routes are available by testing environment | ||
| const isGitHubPages = window.location.hostname.includes('github.io'); | ||
| return isGitHubPages || !process.env.NEXT_PUBLIC_API_AVAILABLE; | ||
| } |
There was a problem hiding this comment.
The function returns false during server-side rendering (SSR) when window is undefined, but this could cause hydration mismatches. The logic should be consistent between server and client, or the function should only be used client-side.
| // Add form-specific data | ||
| if (formType === 'RSVP') { | ||
| const rsvpData = data as RSVPFormData; | ||
| const userEmail = rsvpData.contact?.email || rsvpData.email || 'codestromhub@gmail.com'; |
There was a problem hiding this comment.
Falling back to 'codestromhub@gmail.com' when user email is missing could result in emails being sent to the wrong recipient. Consider requiring email validation or using a different fallback strategy.
| formData.append('message', formatRSVPMessage(rsvpData)); | ||
| } else { | ||
| const contactData = data as ContactFormData; | ||
| const userEmail = contactData.email || 'codestromhub@gmail.com'; |
There was a problem hiding this comment.
Falling back to 'codestromhub@gmail.com' when user email is missing could result in emails being sent to the wrong recipient. Consider requiring email validation or using a different fallback strategy.
Problem
The wedding website deployment to GitHub Pages was failing due to several critical issues:
/images/photo.jpgdidn't account for the GitHub Pages subdirectory (/Sharothee-Wedding-arvinwedsincia/)/api/rsvp/formAPI route which doesn't exist in static exports/api/contactAPI route unavailable in static modeSolution
Implemented a hybrid serverless architecture that works seamlessly in both static (GitHub Pages) and server (VPS/Vercel) environments.
Image Loading Fix
Created a
assetUrl()helper function that automatically handles basePath:Result:
/images/story/couple.jpeg/Sharothee-Wedding-arvinwedsincia/images/story/couple.jpegFixed 24+ image references across homepage, events page, and components.
Form Submission Solution
Created
src/lib/serverless-forms.tswith intelligent environment detection:Benefits:
Email Configuration
Web3Forms is configured to send form submissions with the following settings:
This ensures all form notifications are sent from the wedding team's email address while keeping arvincia@sparrow-group.com informed of all submissions.
Configuration Updates
Updated
next.config.tsto properly detect GitHub Pages builds:Updated GitHub Actions workflow to set
GITHUB_PAGES=trueduring build.Changes Summary
Code Files (9 modified)
client/next.config.ts- GitHub Pages configuration with environment detectionclient/src/lib/utils.ts- AddedassetUrl()andgetBasePath()helpersclient/src/lib/serverless-forms.ts- NEW - Serverless form submission handler with email configurationclient/src/app/page.tsx- Fixed 17 image pathsclient/src/app/events/page.tsx- Fixed dynamic image pathsclient/src/app/rsvp/page.tsx- Integrated serverless form submissionclient/src/app/contact/page.tsx- Integrated serverless form submissionclient/src/components/HeartCollage.tsx- Updated default image props.github/workflows/nextjs.yml- Added build environment variablesDocumentation (5 new guides)
DEPLOYMENT_READY.md- Quick start guide for deploymentQUICK_DEPLOY.md- 3-step deployment referenceGITHUB_PAGES_SETUP.md- Complete setup with troubleshootingCHANGES_SUMMARY.md- Visual guide of all modificationsIMPLEMENTATION_SUMMARY.md- Technical implementation detailsAll documentation has been updated to reflect the email configuration settings.
Testing
All quality checks passed:
Deployment
3-Step Process:
NEXT_PUBLIC_WEB3FORMS_KEYLive URL: https://codestorm-hub.github.io/Sharothee-Wedding-arvinwedsincia/
Performance Improvements
Breaking Changes
None. The implementation maintains full backward compatibility with server deployments (VPS/Vercel/Netlify).
What Works
GitHub Pages (Static Mode):
Server Mode (VPS/Vercel):
Notes
Closes #[issue-number]
Original prompt
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.