Skip to content

Seo improve#26

Merged
VivekGupta137 merged 12 commits intomasterfrom
seo-improve
Mar 18, 2026
Merged

Seo improve#26
VivekGupta137 merged 12 commits intomasterfrom
seo-improve

Conversation

@VivekGupta137
Copy link
Copy Markdown
Owner

No description provided.

Copilot AI review requested due to automatic review settings February 2, 2026 19:14
Copy link
Copy Markdown
Owner Author

@VivekGupta137 VivekGupta137 left a comment

Choose a reason for hiding this comment

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

lj

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Feb 2, 2026

Deploying ninjatype with  Cloudflare Pages  Cloudflare Pages

Latest commit: c606d58
Status:🚫  Build failed.

View logs

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request implements comprehensive SEO improvements for the NinjaType typing practice application, including structured data markup, performance optimizations, PWA features, accessibility enhancements, and automated monitoring tools.

Changes:

  • Added structured data (Schema.org) with Organization, Website, WebApplication, and WebPage schemas
  • Implemented RSS feed for content discovery
  • Added PWA manifest with app shortcuts and service worker configuration
  • Integrated Partytown for offloading analytics to web workers
  • Added security headers via Cloudflare Pages _headers file
  • Implemented View Transitions for smoother navigation
  • Added skip-to-content link for accessibility
  • Configured Lighthouse CI and Unlighthouse for automated performance monitoring
  • Added rehype plugins for external link security and heading anchors
  • Optimized font loading with preload and display parameters

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
src/lib/schema-templates.ts New library for type-safe Schema.org structured data templates
src/pages/rss.xml.ts RSS feed endpoint with static content items for main pages
src/pages/index.astro Added comprehensive structured data (Organization, Website, WebApplication)
src/pages/learn/index.astro Added WebPage schema with structured data
src/pages/history.astro Added WebPage schema for history tracking page
src/pages/[mdid].astro Added WebPage schema for dynamic content pages, improved code formatting
src/layouts/BaseLayout.astro Added View Transitions, Partytown integration, skip link for accessibility
src/components/common/CommonHead.astro Added DNS prefetch, font preloading, RSS discovery link
src/components/Header.astro Moved font link to CommonHead, minor formatting fixes
public/favicon/manifest.json Enhanced PWA manifest with shortcuts, screenshots, and metadata
public/_headers New Cloudflare security headers with HSTS, CSP, X-Frame-Options, cache control
unlighthouse.config.ts Configuration for site-wide Lighthouse audits
lighthouserc.js Lighthouse CI configuration with performance budgets and assertions
.eslintrc.json ESLint configuration for accessibility linting (jsx-a11y)
.github/workflows/lighthouse.yml GitHub Actions workflow for automated Lighthouse CI on PRs
astro.config.mjs Added compress, partytown, rehype plugins, PWA service worker configuration
package.json Added SEO and monitoring dependencies, new npm scripts for auditing
plan/*.md Extensive documentation of implementation phases and progress
Comments suppressed due to low confidence (1)

src/pages/[mdid].astro:104

  • Using new Date().toISOString() at build time will set both dateModified and publishDate to whenever the site is built, not when the content actually changes. This means every build will show all pages as "just modified" and "just published" even if their content hasn't changed. Consider either:
  1. Removing these dates if you don't track actual modification/publication dates
  2. Implementing a proper content versioning system to track real dates
  3. Using static dates that represent actual content changes
        dateModified: new Date().toISOString(),
    }),
);
---

<BaseLayout
    title={seo.title}
    description={seo.description}
    canonical={canonicalURL}
    type="article"
>
    <script
        type="application/ld+json"
        set:html={JSON.stringify(schemaMarkup)}
    />

    <link
        slot="head"
        rel="stylesheet"
        href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,1,0&icon_names=fiber_manual_record&display=block"
    />

    <ArticleSchema
        title={seo.title}
        description={seo.description}
        author="NinjaType Team"
        publishDate={new Date().toISOString()}

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

Comment on lines +22 to +25
href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600&display=swap"
rel="stylesheet"
/>
<link
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The Nunito font is being loaded twice: once as a regular stylesheet (lines 21-24) and once via preload (lines 39-44). The preload with the onload trick should replace the regular link, not be added alongside it. Remove the regular stylesheet link at lines 21-24 since the preload mechanism already loads the font.

Suggested change
href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600&display=swap"
rel="stylesheet"
/>
<link

Copilot uses AI. Check for mistakes.

# Note: Adjust these directives based on your actual needs

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com https://scripts.simpleanalyticscdn.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com data:; img-src 'self' data: https:; connect-src 'self' https://www.google-analytics.com https://queue.simpleanalyticscdn.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self';
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The Content Security Policy includes 'unsafe-inline' and 'unsafe-eval' in the script-src directive, which significantly weakens security protections against XSS attacks. While these may be needed for analytics and the current implementation, consider:

  1. Using nonces or hashes for inline scripts instead of 'unsafe-inline'
  2. Moving away from 'unsafe-eval' by refactoring any code that requires it
  3. At minimum, document why these are necessary and create a plan to remove them

Copilot uses AI. Check for mistakes.
name: "Learn Touch Typing Free - Progressive Typing Lessons",
description:
"Learn touch typing for free with NinjaType's progressive lessons. Practice each finger individually, improve typing speed and accuracy, and master proper keyboard technique.",
dateModified: new Date().toISOString(),
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

Using new Date().toISOString() at build time will set the dateModified to whenever the site is built, not when the content actually changes. This means every build will show all pages as "just modified" even if their content hasn't changed. Consider either:

  1. Removing dateModified if you don't track actual modification dates
  2. Implementing a proper content versioning system to track real modification dates
  3. Using static dates that represent actual content changes
Suggested change
dateModified: new Date().toISOString(),

Copilot uses AI. Check for mistakes.
site: "https://ninjatype.com",
scanner: {
// Run multiple samples for accuracy
samples: 1,
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The samples configuration is set to 1, which provides less accurate results. The plan documentation (plan/ninjatype-seo-implementation.md line 1187) recommends using samples: 3 for better accuracy. Consider increasing this to at least 3 samples to get more reliable Lighthouse scores.

Suggested change
samples: 1,
samples: 3,

Copilot uses AI. Check for mistakes.
// Run multiple samples for accuracy
samples: 1,
// Throttle like mobile
throttle: false,
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

Throttling is disabled (throttle: false), which means the audit won't simulate real-world mobile network conditions. This can result in overly optimistic performance scores that don't reflect actual user experience. Enable throttling to get more realistic performance metrics: throttle: true

Suggested change
throttle: false,
throttle: true,

Copilot uses AI. Check for mistakes.
link: item.link,
})),
customData: `<language>en-us</language>`,
stylesheet: "/rss/styles.xsl",
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The RSS feed references a stylesheet at "/rss/styles.xsl" that doesn't exist in the repository. This will result in a 404 error when RSS readers try to fetch the stylesheet. Either remove the stylesheet reference or create the XSL file to style the RSS feed in browsers.

Suggested change
stylesheet: "/rss/styles.xsl",

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +74
aggregateRating: {
"@type": "AggregateRating",
ratingValue: "4.8",
ratingCount: "150",
bestRating: "5",
worstRating: "1",
},
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The aggregate rating values (4.8 rating with 150 reviews) appear to be placeholder or fake data. Including fabricated reviews in structured data violates Google's guidelines and can result in manual penalties. Either remove the aggregateRating field entirely, or only include it if you have legitimate, verifiable reviews from real users.

Suggested change
aggregateRating: {
"@type": "AggregateRating",
ratingValue: "4.8",
ratingCount: "150",
bestRating: "5",
worstRating: "1",
},

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +34
pubDate: new Date("2024-01-01"),
},
{
title: "Learn Touch Typing Free - Progressive Typing Lessons",
link: "/learn",
description:
"Learn touch typing for free with NinjaType's progressive lessons. Practice each finger individually, improve typing speed and accuracy, and master proper keyboard technique.",
pubDate: new Date("2024-01-01"),
},
{
title: "Typing Speed History - Track Your WPM Progress",
link: "/history",
description:
"Track your typing speed history and WPM progress with detailed statistics and charts. View lifetime best scores, daily records, and accuracy trends.",
pubDate: new Date("2024-01-01"),
},
{
title: "About NinjaType",
link: "/about",
description:
"Learn about NinjaType, a free online typing test and speed practice platform. No registration required.",
pubDate: new Date("2024-01-01"),
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The pubDate uses "2024-01-01" which is in the past, while the implementation summary documents indicate this work was done in "February 2026" (per implementation-progress.md). Using accurate publication dates is important for RSS feed relevance and SEO. Consider using the actual date when these pages were created or last significantly updated.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,52 @@
import rss from "@astrojs/rss";
import { getCollection } from "astro:content";
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The getCollection function is imported but never used. The RSS feed uses static content items instead of dynamic content from collections. Either remove this unused import or implement dynamic content collection if that was the intended design.

Suggested change
import { getCollection } from "astro:content";

Copilot uses AI. Check for mistakes.
name: "Typing Speed History - Track Your WPM Progress",
description:
"Track your typing speed history and WPM progress with detailed statistics and charts. View lifetime best scores, daily records, accuracy trends, and typing test results.",
dateModified: new Date().toISOString(),
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

Using new Date().toISOString() at build time will set the dateModified to whenever the site is built, not when the content actually changes. This means every build will show all pages as "just modified" even if their content hasn't changed. Consider either:

  1. Removing dateModified if you don't track actual modification dates
  2. Implementing a proper content versioning system to track real modification dates
  3. Using static dates that represent actual content changes
Suggested change
dateModified: new Date().toISOString(),

Copilot uses AI. Check for mistakes.
@VivekGupta137
Copy link
Copy Markdown
Owner Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copy link
Copy Markdown

Copilot AI commented Feb 2, 2026

@VivekGupta137 I've opened a new pull request, #27, to work on those changes. Once the pull request is ready, I'll request review from you.

@VivekGupta137 VivekGupta137 merged commit c606d58 into master Mar 18, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants