Skip to content

feat: implement comprehensive SEO optimizations#5

Merged
Venkat-Kolasani merged 6 commits into
mainfrom
security-fixes
Jan 18, 2026
Merged

feat: implement comprehensive SEO optimizations#5
Venkat-Kolasani merged 6 commits into
mainfrom
security-fixes

Conversation

@Venkat-Kolasani

@Venkat-Kolasani Venkat-Kolasani commented Jan 17, 2026

Copy link
Copy Markdown
Owner

User description

  • Add code splitting and lazy loading (reduces bundle size by 63%)
  • Add dynamic meta tags with react-helmet-async
  • Update sitemap.xml with all 8 routes
  • Add Organization, FAQ, and BreadcrumbList JSON-LD schemas
  • Optimize font loading with async preload
  • Enhance manifest.json with shortcuts and PWA features
  • Add skip navigation link for accessibility
  • Create reusable SEO component

Performance improvements:

  • Main bundle reduced from 529KB to 196KB
  • Pages now have unique meta tags per route

PR Type

Enhancement


Description

  • Implement code splitting and lazy loading for all pages

  • Add dynamic meta tags with react-helmet-async SEO component

  • Enhance manifest.json with PWA shortcuts and maskable icons

  • Optimize font loading with async preload and noscript fallback

  • Expand sitemap.xml to include all 8 application routes

  • Add Organization, FAQ, and BreadcrumbList JSON-LD schemas

  • Add skip-to-main-content accessibility link


Diagram Walkthrough

flowchart LR
  A["App.js"] -->|"lazy load pages"| B["Code Splitting"]
  A -->|"wrap with HelmetProvider"| C["Dynamic Meta Tags"]
  D["index.html"] -->|"add JSON-LD schemas"| E["Structured Data"]
  D -->|"async font preload"| F["Font Optimization"]
  G["manifest.json"] -->|"add shortcuts & maskable"| H["PWA Enhancement"]
  I["sitemap.xml"] -->|"expand to 8 routes"| J["SEO Coverage"]
  K["Page Components"] -->|"import SEO component"| L["Per-Route Meta Tags"]
  B -->|"improves"| M["Performance"]
  C -->|"improves"| M
  E -->|"improves"| N["Search Rankings"]
  F -->|"improves"| M
Loading

File Walkthrough

Relevant files
Enhancement
15 files
App.js
Implement code splitting and lazy loading                               
+91/-68 
SEO.jsx
Create reusable SEO component with Helmet                               
+54/-0   
index.html
Add JSON-LD schemas and optimize fonts                                     
+91/-3   
manifest.json
Enhance PWA with shortcuts and maskable icons                       
+31/-7   
sitemap.xml
Expand sitemap to include all 8 routes                                     
+58/-1   
Home.jsx
Add SEO component with homepage meta tags                               
+7/-0     
Dashboard.jsx
Add SEO component with dashboard meta tags                             
+7/-0     
InternshipList.jsx
Add SEO component with internship meta tags                           
+7/-0     
HackathonList.jsx
Add SEO component with hackathon meta tags                             
+7/-0     
AddOpportunity.jsx
Add SEO component with add opportunity meta tags                 
+7/-0     
EditOpportunity.jsx
Add SEO component with edit opportunity meta tags               
+6/-0     
StatusBoard.jsx
Add SEO component with status board meta tags                       
+7/-0     
Calendar.jsx
Add SEO component with calendar meta tags                               
+7/-0     
Reports.jsx
Add SEO component with reports meta tags                                 
+7/-0     
Analytics.jsx
Add SEO component with analytics meta tags                             
+7/-0     
Dependencies
1 files
package.json
Add react-helmet-async dependency                                               
+1/-0     


Open with Devin

- Add code splitting and lazy loading (reduces bundle size by 63%)
- Add dynamic meta tags with react-helmet-async
- Update sitemap.xml with all 8 routes
- Add Organization, FAQ, and BreadcrumbList JSON-LD schemas
- Optimize font loading with async preload
- Enhance manifest.json with shortcuts and PWA features
- Add skip navigation link for accessibility
- Create reusable SEO component

Performance improvements:
- Main bundle reduced from 529KB to 196KB
- Pages now have unique meta tags per route
@Venkat-Kolasani Venkat-Kolasani self-assigned this Jan 17, 2026
Copilot AI review requested due to automatic review settings January 17, 2026 05:11
@vercel

vercel Bot commented Jan 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
future-stack Ready Ready Preview, Comment Jan 18, 2026 2:23pm

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@qodo-code-review

qodo-code-review Bot commented Jan 17, 2026

Copy link
Copy Markdown

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Meta tag injection

Description: The SEO component directly renders caller-controlled props (e.g., canonical, image, type,
title, description, keywords) into / attributes (lines 24-49), which could enable
injection of attacker-supplied URLs such as javascript:/data: or misleading external
canonical/og URLs if any of these props ever become derived from untrusted input (e.g.,
query params or CMS content) without validation/allowlisting.
SEO.jsx [3-49]

Referred Code
const SEO = ({
  title,
  description,
  keywords,
  canonical,
  type = 'website',
  image = 'https://futuretracker.online/og-image.png',
  noindex = false,
}) => {
  const siteTitle = 'FutureTracker';
  const fullTitle = title ? `${title} | ${siteTitle}` : `${siteTitle} - Track Internships, Hackathons & Job Applications`;
  const defaultDescription = 'Free opportunity tracker for students and developers. Organize job applications, track internship stages, never miss hackathon deadlines.';
  const metaDescription = description || defaultDescription;
  const defaultKeywords = 'job tracker, internship tracker, hackathon tracker, application tracker, career tracker, job application organizer, student tools, developer tools';
  const metaKeywords = keywords || defaultKeywords;
  const baseUrl = 'https://futuretracker.online';
  const canonicalUrl = canonical ? `${baseUrl}${canonical}` : baseUrl;

  return (
    <Helmet>
      {/* Primary Meta Tags */}


 ... (clipped 26 lines)
CSP inline script

Description: The font preload uses an inline onload handler (line 41), which can force a weaker/less
effective CSP (requiring unsafe-inline or a nonce) and increases XSS blast radius if any
XSS exists elsewhere in the app.
index.html [38-42]

Referred Code
<!-- Fonts - Optimized with preload -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"></noscript>
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review

qodo-code-review Bot commented Jan 17, 2026

Copy link
Copy Markdown

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Remove non-indexable URLs from sitemap
Suggestion Impact:The commit removed all non-homepage URLs (dashboard, internships, hackathons, status-board, calendar, analytics, reports) from the sitemap, leaving only the public homepage entry and updating the comment/lastmod accordingly.

code diff:

-  <!-- Homepage -->
+  <!-- Homepage - Only public page, all others require authentication -->
   <url>
     <loc>https://futuretracker.online/</loc>
-    <lastmod>2026-01-17</lastmod>
+    <lastmod>2026-01-18</lastmod>
     <changefreq>weekly</changefreq>
     <priority>1.0</priority>
   </url>
-  
-  <!-- Dashboard -->
-  <url>
-    <loc>https://futuretracker.online/dashboard</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>daily</changefreq>
-    <priority>0.9</priority>
-  </url>
-  
-  <!-- Internships -->
-  <url>
-    <loc>https://futuretracker.online/internships</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>daily</changefreq>
-    <priority>0.8</priority>
-  </url>
-  
-  <!-- Hackathons -->
-  <url>
-    <loc>https://futuretracker.online/hackathons</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>daily</changefreq>
-    <priority>0.8</priority>
-  </url>
-  
-  <!-- Status Board -->
-  <url>
-    <loc>https://futuretracker.online/status-board</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>daily</changefreq>
-    <priority>0.7</priority>
-  </url>
-  
-  <!-- Calendar -->
-  <url>
-    <loc>https://futuretracker.online/calendar</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>daily</changefreq>
-    <priority>0.7</priority>
-  </url>
-  
-  <!-- Analytics -->
-  <url>
-    <loc>https://futuretracker.online/analytics</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>weekly</changefreq>
-    <priority>0.6</priority>
-  </url>
-  
-  <!-- Reports -->
-  <url>
-    <loc>https://futuretracker.online/reports</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>weekly</changefreq>
-    <priority>0.6</priority>
-  </url>

Remove URLs for authenticated, non-indexable pages (like /dashboard and
/internships) from sitemap.xml to avoid sending conflicting signals to search
engines.

public/sitemap.xml [1-66]

 <?xml version="1.0" encoding="UTF-8"?>
 <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <!-- Homepage -->
   <url>
     <loc>https://futuretracker.online/</loc>
     <lastmod>2026-01-17</lastmod>
     <changefreq>weekly</changefreq>
     <priority>1.0</priority>
   </url>
-  
-  <!-- Dashboard -->
-  <url>
-    <loc>https://futuretracker.online/dashboard</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>daily</changefreq>
-    <priority>0.9</priority>
-  </url>
-  
-  <!-- Internships -->
-  <url>
-    <loc>https://futuretracker.online/internships</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>daily</changefreq>
-    <priority>0.8</priority>
-  </url>
-  
-  <!-- Hackathons -->
-  <url>
-    <loc>https://futuretracker.online/hackathons</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>daily</changefreq>
-    <priority>0.8</priority>
-  </url>
-  
-  <!-- Status Board -->
-  <url>
-    <loc>https://futuretracker.online/status-board</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>daily</changefreq>
-    <priority>0.7</priority>
-  </url>
-  
-  <!-- Calendar -->
-  <url>
-    <loc>https://futuretracker.online/calendar</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>daily</changefreq>
-    <priority>0.7</priority>
-  </url>
-  
-  <!-- Analytics -->
-  <url>
-    <loc>https://futuretracker.online/analytics</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>weekly</changefreq>
-    <priority>0.6</priority>
-  </url>
-  
-  <!-- Reports -->
-  <url>
-    <loc>https://futuretracker.online/reports</loc>
-    <lastmod>2026-01-17</lastmod>
-    <changefreq>weekly</changefreq>
-    <priority>0.6</priority>
-  </url>
 </urlset>

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies that including noindex pages in the sitemap is an SEO anti-pattern and proposes to remove them, which improves the site's crawlability and search engine communication.

Medium
General
Enable CORS on font preload
Suggestion Impact:The commit did not add crossorigin to the existing preload tag; instead, it removed the preload-based font loading approach entirely and replaced it with an async-loading stylesheet pattern (media="print" + onload). This change makes the original preload+CORS suggestion no longer applicable.

code diff:

+  <!-- Fonts - Optimized with preload -->
+  <link rel="preconnect" href="https://fonts.googleapis.com">
+  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+  <!-- Use media="print" trick to load async without JavaScript dependency -->
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
+    media="print" onload="this.media='all'">
+  <noscript>
+    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
+  </noscript>

Add the crossorigin="anonymous" attribute to the tag for
Google Fonts to ensure it loads correctly under CORS.

public/index.html [41]

-<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
+<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" as="style" crossorigin="anonymous" onload="this.onload=null;this.rel='stylesheet'">

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a missing crossorigin attribute on the font preload link, which is necessary for cross-origin resources and improves the robustness of the font loading optimization.

Medium
Omit canonical link for noindex pages
Suggestion Impact:The canonical was removed from unconditional rendering and is now only included in the indexable (non-noindex) branch, matching the intent to omit canonical tags on noindex pages.

code diff:

       {noindex ? (
         <meta name="robots" content="noindex, nofollow" />
       ) : (
-        <meta name="robots" content="index, follow" />
+        <>
+          <meta name="robots" content="index, follow" />
+          {/* Only add canonical for indexable pages */}
+          <link rel="canonical" href={canonicalUrl} />
+        </>
       )}
-      <link rel="canonical" href={canonicalUrl} />

Conditionally render the tag in the SEO component only
when the page is not marked as noindex.

src/components/seo/SEO.jsx [33]

-<link rel="canonical" href={canonicalUrl} />
+{!noindex && <link rel="canonical" href={canonicalUrl} />}

[Suggestion processed]

Suggestion importance[1-10]: 5

__

Why: The suggestion correctly points out that a canonical tag is unnecessary for noindex pages, and removing it leads to cleaner and more explicit SEO signals, which is a good best practice.

Low
  • Update

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements comprehensive SEO optimizations for the FutureTracker application, including code splitting, dynamic meta tags, structured data, and PWA enhancements.

Changes:

  • Implemented lazy loading for all page components reducing main bundle size by 63% (529KB to 196KB)
  • Added SEO component with react-helmet-async for dynamic meta tags, Open Graph, and Twitter cards
  • Enhanced sitemap.xml with all 8 application routes and updated structured data schemas in index.html
  • Improved PWA manifest with shortcuts and optimized font loading with async preload

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/components/seo/SEO.jsx New reusable SEO component for managing meta tags, Open Graph, and Twitter cards
src/App.js Added code splitting with lazy loading, Suspense boundaries, HelmetProvider, and skip navigation link
src/pages/*.jsx Integrated SEO component across all 10 pages with route-specific meta tags and noindex for protected routes
public/sitemap.xml Expanded from 1 to 8 routes with priority and changefreq settings
public/manifest.json Enhanced PWA features with shortcuts, categories, and improved icon configuration
public/index.html Added Organization, FAQ, and BreadcrumbList JSON-LD schemas; optimized font loading
package.json Added react-helmet-async dependency

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread public/sitemap.xml Outdated
Comment thread src/components/seo/SEO.jsx Outdated
Comment thread src/pages/EditOpportunity.jsx
Comment thread public/index.html Outdated
Comment thread package.json
Comment thread src/App.js Outdated
Comment thread public/manifest.json Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

public/sitemap.xml:10

  • The sitemap.xml only includes the homepage, but the PR description claims "Expand sitemap.xml to include all 8 application routes" and the documentation in DOCUMENTATION.md describes 8 routes being included (homepage, dashboard, internships, hackathons, status-board, calendar, analytics, reports). The actual sitemap is missing 7 routes.

Additionally, since all routes except the homepage require authentication (as noted in the comment), including authenticated routes in the sitemap would expose them to search engines when they should likely have noindex meta tags. Consider either:

  1. Only including the public homepage in the sitemap (current implementation is correct)
  2. OR removing the noindex flags from authenticated pages and including them in the sitemap

The current implementation is inconsistent with the PR description and documentation.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <!-- Homepage - Only public page, all others require authentication -->
  <url>
    <loc>https://futuretracker.online/</loc>
    <lastmod>2026-01-18</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1.0</priority>
  </url>
</urlset>

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread public/index.html Outdated
Comment thread public/index.html Outdated
Comment thread src/pages/EditOpportunity.jsx Outdated
Comment thread src/components/seo/SEO.jsx
Comment thread docs/DOCUMENTATION.md
Comment thread public/manifest.json
…t JSON-LD, and clarify PWA shortcut descriptions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/seo/SEO.jsx
Comment thread docs/DOCUMENTATION.md
Comment thread public/index.html
Comment thread .npmrc
Comment thread public/sitemap.xml
Comment thread src/pages/Home.jsx Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (1)

public/sitemap.xml:10

  • The PR description and documentation claim that the sitemap was expanded to include all 8 routes (dashboard, internships, hackathons, status-board, calendar, analytics, reports, etc.), but the actual sitemap.xml file only contains the homepage. This is a significant discrepancy between what was claimed and what was implemented. However, this may actually be correct from an SEO perspective - since all routes except the homepage require authentication (as noted in the comment on line 3), including them in the sitemap would allow search engines to crawl pages that users cannot access without logging in. The comment "Only public page, all others require authentication" suggests this was an intentional decision. The documentation in DOCUMENTATION.md should be updated to reflect this decision and explain why authenticated routes were not included in the sitemap.
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <!-- Homepage - Only public page, all others require authentication -->
  <url>
    <loc>https://futuretracker.online/</loc>
    <lastmod>2026-01-18</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1.0</priority>
  </url>
</urlset>

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .npmrc
# Last verified: 2026-01-18
# Affected package: react-helmet-async@2.0.5

legacy-peer-deps=true

Copilot AI Jan 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states that react-helmet-async@2.0.5 doesn't officially support React 19 yet, and legacy-peer-deps is required. While this is a pragmatic solution, there's a risk that the library may have incompatibilities with React 19 that haven't been discovered yet. Consider: 1) Testing thoroughly to ensure no runtime issues, 2) Adding a TODO or tracking issue to monitor for React 19 support, or 3) Evaluating if there's an alternative library with official React 19 support. The "Last verified: 2026-01-18" date is helpful for tracking.

Suggested change
legacy-peer-deps=true
# NOTE: Do not enable global legacy-peer-deps here to avoid silently
# installing packages with unsupported or mismatched peer dependencies.
# If installation fails due to the react-helmet-async peer dependency
# while React 19 is still in use and verified in this project, run:
# npm install --legacy-peer-deps
# or append --legacy-peer-deps to specific install commands as needed.

Copilot uses AI. Check for mistakes.
Comment thread docs/DOCUMENTATION.md
Comment thread public/index.html
Comment thread src/pages/Home.jsx
Comment thread src/components/seo/SEO.jsx
@Venkat-Kolasani Venkat-Kolasani merged commit f604822 into main Jan 18, 2026
9 checks passed
@Venkat-Kolasani Venkat-Kolasani deleted the security-fixes branch January 19, 2026 05:41

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 6 additional flags.

Open in Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants