Skip to content

feat: improve seo#3

Merged
Shewart merged 8 commits intomainfrom
feat/seo
Feb 14, 2026
Merged

feat: improve seo#3
Shewart merged 8 commits intomainfrom
feat/seo

Conversation

@Shewart
Copy link
Contributor

@Shewart Shewart commented Feb 14, 2026

This pull request introduces several improvements and new features to the ShellUI project, focusing on enhanced error handling, improved metadata and SEO support, better accessibility and theming for UI components, and the addition of configuration and schema support for the ShellUI CLI. Below are the most important changes grouped by theme:

Error Handling and User Experience:

  • Added a new reusable ErrorPage component (error-page.tsx) and updated both app/not-found.tsx and app/(home)/not-found.tsx to use it, providing a consistent and user-friendly error page across the app. [1] [2] [3]

Metadata, SEO, and Analytics:

  • Refactored metadata management by introducing a createMetadata utility and updating app/layout.tsx to use it, including improved Open Graph and Twitter metadata, canonical URLs, and extensive keywords for SEO. [1] [2]
  • Added Google Analytics 4 integration and application-level JSON-LD structured data for better analytics and search engine understanding.
  • Implemented dynamic robots.txt and sitemap.xml endpoints for improved SEO and crawler support. [1] [2]

UI Components and Theming:

  • Improved the InstallAnimation component to use text-foreground and dark:text-white classes for better accessibility and theme support, replacing hardcoded color classes. [1] [2] [3] [4] [5] [6] [7] [8]
  • Added a new, highly customizable Button component using class-variance-authority for consistent styling and variants.
  • Updated dependencies to include radix-ui for improved UI primitives.

Configuration and Schema Support:

  • Added a public JSON schema (schema.json) for validating shellui.json configuration files, enhancing CLI usability and editor integration.

These changes collectively enhance the developer and user experience, improve SEO and analytics, and lay the groundwork for better customization and maintainability.

Copilot AI review requested due to automatic review settings February 14, 2026 17:49
@vercel
Copy link
Contributor

vercel bot commented Feb 14, 2026

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

Project Deployment Actions Updated (UTC)
shellui-docs Ready Ready Preview, Comment Feb 14, 2026 5:57pm

Copy link
Contributor

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 introduces comprehensive SEO improvements, error handling enhancements, and UI component additions to the ShellUI project. The changes focus on improving search engine visibility, user experience, and component library functionality.

Changes:

  • Added SEO infrastructure including dynamic sitemap.xml, robots.txt, Google Analytics 4 integration, and structured data (JSON-LD) for better search engine understanding
  • Introduced reusable error page component with consistent styling and not-found pages for improved error handling across the application
  • Enhanced theming and accessibility in the InstallAnimation component by replacing hardcoded colors with semantic color classes
  • Added Button component with comprehensive variants using class-variance-authority for consistent styling
  • Created JSON schema for shellui.json configuration validation to improve CLI usability and editor integration

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
shellui/public/schema.json Provides JSON schema for validating ShellUI configuration files, enabling better IDE support and validation
shellui/package.json Adds radix-ui dependency for UI primitives support
shellui/lib/metadata.ts Introduces metadata creation utility with Open Graph and Twitter card support for consistent SEO metadata
shellui/components/ui/error-page.tsx Implements reusable error page component with illustration and call-to-action
shellui/components/ui/button.tsx Adds fully-featured Button component with variants and asChild pattern support
shellui/components/install-animation.tsx Improves theming with semantic color classes for better dark mode support
shellui/app/sitemap.ts Implements dynamic sitemap generation for improved SEO and crawler support
shellui/app/robots.ts Adds robots.txt configuration for search engine crawler control
shellui/app/not-found.tsx Implements top-level not-found page using the new error component
shellui/app/layout.tsx Enhances root layout with metadata, Google Analytics, and structured data
shellui/app/(home)/not-found.tsx Adds route-specific not-found page
shellui/bun.lock Updates lock file with new dependencies

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

Comment on lines +19 to +20
title:
override.title ?? "ShellUI – CLI-first, shadcn-inspired Blazor components",
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The same title extraction issue exists here. When override.title is an object with template and default properties, this will not work as expected.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,30 @@
import { Button } from "@/components/ui/button"

const Error = () => {
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The component name "Error" conflicts with the built-in JavaScript Error object. This could cause confusion and potential issues. Consider renaming the component to "ErrorPage" or "NotFoundError" to avoid this naming collision.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,64 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The button.tsx component imports and uses class-variance-authority (cva) but this package is not listed in package.json dependencies. This will cause a runtime error. Add "class-variance-authority" to the dependencies.

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +8
<h2 className='mb-6 text-5xl font-semibold'>Whoops!</h2>
<h3 className='mb-1.5 text-3xl font-semibold'>Something went wrong</h3>
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The heading hierarchy is incorrect. The page uses h2 followed by h3 without an h1. For proper document structure and accessibility, the main heading should be h1, not h2. Change the "Whoops!" heading to h1 and "Something went wrong" to h2.

Suggested change
<h2 className='mb-6 text-5xl font-semibold'>Whoops!</h2>
<h3 className='mb-1.5 text-3xl font-semibold'>Something went wrong</h3>
<h1 className='mb-6 text-5xl font-semibold'>Whoops!</h1>
<h2 className='mb-1.5 text-3xl font-semibold'>Something went wrong</h2>

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +30
import { Button } from "@/components/ui/button"

const Error = () => {
return (
<div className='grid min-h-screen grid-cols-1 lg:grid-cols-2'>
<div className='flex flex-col items-center justify-center px-4 py-8 text-center'>
<h2 className='mb-6 text-5xl font-semibold'>Whoops!</h2>
<h3 className='mb-1.5 text-3xl font-semibold'>Something went wrong</h3>
<p className='text-muted-foreground mb-6 max-w-sm'>
The page you&apos;re looking for isn&apos;t found, we suggest you back to home.
</p>
<Button asChild size='lg' className='rounded-lg text-base'>
<a href='/'>Back to home page</a>
</Button>
</div>

{/* Right Section: Illustration */}
<div className='relative max-h-screen w-full p-2 max-lg:hidden'>
<div className='h-full w-full rounded-2xl bg-transparent'></div>
<img
src='https://cdn.shadcnstudio.com/ss-assets/blocks/marketing/error/image-1.png'
alt='404 illustration'
className='absolute top-1/2 left-1/2 h-[clamp(260px,25vw,406px)] -translate-x-1/2 -translate-y-1/2'
/>
</div>
</div>
)
}

export default Error
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

Inconsistent quote style: This file uses single quotes while the rest of the codebase uses double quotes. For consistency, use double quotes throughout.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,7 @@
import Error from '@/components/ui/error-page'
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

Inconsistent quote style: This file uses single quotes while the rest of the codebase (including app/(home)/not-found.tsx) uses double quotes. For consistency, use double quotes throughout.

Suggested change
import Error from '@/components/ui/error-page'
import Error from "@/components/ui/error-page"

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +8
title:
override.title ?? "ShellUI – CLI-first, shadcn-inspired Blazor components",
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The title extraction logic may not work correctly. When override.title is an object (e.g., { template: "%s | ShellUI", default: "..." }), accessing it directly will not give the expected string. Consider using override.title?.default ?? override.title or handling the case where title is an object with a template property.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,64 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { Slot } from "radix-ui"
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The import statement should be import { Slot } from "@radix-ui/react-slot" instead of import { Slot } from "radix-ui". While the "radix-ui" meta-package re-exports all Radix components, using the specific package import is the recommended practice and ensures better tree-shaking and follows the patterns established in the codebase.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +6
import Error from '@/components/ui/error-page'

const ErrorPage = () => {
return <Error />
}

Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

Inconsistent naming: the component is imported as "Error" but the component in error-page.tsx is exported as default with the name "Error", while in the other not-found.tsx file it's imported as "ErrorPage". The export should be named consistently, preferably as "ErrorPage" to avoid confusion with the built-in Error object.

Suggested change
import Error from '@/components/ui/error-page'
const ErrorPage = () => {
return <Error />
}
import ErrorPage from '@/components/ui/error-page'

Copilot uses AI. Check for mistakes.
VariantProps<typeof buttonVariants> & {
asChild?: boolean
}) {
const Comp = asChild ? Slot.Root : "button"
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The usage of Slot.Root is incorrect. When importing from @radix-ui/react-slot, the Slot component itself should be used directly, not Slot.Root. Change line 51 to const Comp = asChild ? Slot : "button".

Suggested change
const Comp = asChild ? Slot.Root : "button"
const Comp = asChild ? Slot : "button"

Copilot uses AI. Check for mistakes.
@Shewart Shewart merged commit c9ff2a0 into main Feb 14, 2026
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.

2 participants