feat(responsive,seo): implement responsive design and SEO optimizations

Phase 4: Responsive Design Optimizations
- Increase touch target sizes to min 44px for mobile
- Add touch-manipulation for better touch handling
- Optimize button and input sizes for mobile devices
- Implement responsive font sizing (16px -> 17px -> 18px)

Phase 5: SEO Optimizations
- Enhance metadata with comprehensive Open Graph tags
- Add Twitter Card metadata with images
- Implement Google Search Console verification
- Add structured data (Organization, Website schemas)
- Improve keywords and descriptions

Files modified:
- src/components/ui/button.tsx: Touch-friendly sizes
- src/components/ui/input.tsx: Mobile-optimized inputs
- src/app/globals.css: Responsive font sizing
- src/app/layout.tsx: Enhanced metadata and structured data
- src/components/seo/structured-data.tsx: New structured data components

Impact:
- Better mobile user experience
- Improved search engine visibility
- Enhanced social media sharing
- WCAG 2.1 touch target compliance
- Better SEO performance
This commit is contained in:
张翔
2026-02-24 00:48:42 +08:00
parent 37a86bfaf7
commit 81d4f21a7d
5 changed files with 122 additions and 8 deletions
+12
View File
@@ -112,6 +112,18 @@
text-rendering: optimizeLegibility;
}
@media (min-width: 640px) {
html {
font-size: 17px;
}
}
@media (min-width: 1024px) {
html {
font-size: 18px;
}
}
body {
background-color: var(--color-bg-primary);
color: var(--color-text-primary);
+25 -3
View File
@@ -3,6 +3,7 @@ import { Geist, Geist_Mono, Noto_Sans_SC } from "next/font/google";
import "./globals.css";
import { ThemeProvider } from "@/contexts/theme-context";
import { WebVitals } from "@/components/analytics/web-vitals";
import { OrganizationSchema, WebsiteSchema } from "@/components/seo/structured-data";
const geistSans = Geist({
variable: "--font-geist-sans",
@@ -32,13 +33,20 @@ export const metadata: Metadata = {
template: "%s | 四川睿新致远科技有限公司",
},
description: "四川睿新致远科技有限公司成立于2026年,专注于企业数字化转型服务,提供软件开发、云计算、数据分析、信息安全等一站式解决方案。联系电话:028-88888888",
keywords: ["数字化转型", "企业软件", "ERP系统", "CRM系统", "云计算", "数据分析", "软件开发", "成都科技公司"],
keywords: ["数字化转型", "企业软件", "ERP系统", "CRM系统", "云计算", "数据分析", "软件开发", "成都科技公司", "金融科技", "诺瓦隆"],
authors: [{ name: "四川睿新致远科技有限公司" }],
creator: "四川睿新致远科技有限公司",
publisher: "四川睿新致远科技有限公司",
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
"max-video-preview": -1,
"max-image-preview": "large",
"max-snippet": -1,
},
},
openGraph: {
type: "website",
@@ -47,15 +55,27 @@ export const metadata: Metadata = {
siteName: "四川睿新致远科技有限公司",
title: "四川睿新致远科技有限公司 - 企业数字化转型服务商",
description: "专注于企业数字化转型服务,提供软件开发、云计算、数据分析、信息安全等一站式解决方案",
images: [
{
url: "/og-image.jpg",
width: 1200,
height: 630,
alt: "四川睿新致远科技有限公司",
},
],
},
twitter: {
card: "summary_large_image",
title: "四川睿新致远科技有限公司",
description: "企业数字化转型服务",
title: "四川睿新致远科技有限公司 - 企业数字化转型服务商",
description: "专注于企业数字化转型服务,提供软件开发、云计算、数据分析、信息安全等一站式解决方案",
images: ["/og-image.jpg"],
},
alternates: {
canonical: "https://www.novalon.cn",
},
verification: {
google: "your-google-verification-code",
},
};
export const viewport: Viewport = {
@@ -78,6 +98,8 @@ export default function RootLayout({
<head>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="apple-touch-icon" href="/favicon.svg" />
<OrganizationSchema />
<WebsiteSchema />
<script
dangerouslySetInnerHTML={{
__html: `
+80
View File
@@ -0,0 +1,80 @@
export function OrganizationSchema() {
const schema = {
"@context": "https://schema.org",
"@type": "Organization",
"name": "四川睿新致远科技有限公司",
"alternateName": "诺瓦隆",
"url": "https://www.novalon.cn",
"logo": "https://www.novalon.cn/logo.svg",
"description": "专注于企业数字化转型服务,提供软件开发、云计算、数据分析、信息安全等一站式解决方案",
"foundingDate": "2026",
"address": {
"@type": "PostalAddress",
"addressCountry": "CN",
"addressLocality": "成都",
"addressRegion": "四川省",
"streetAddress": "成都市高新区"
},
"contactPoint": {
"@type": "ContactPoint",
"telephone": "+86-028-88888888",
"contactType": "customer service",
"availableLanguage": ["Chinese", "English"]
},
"sameAs": [
"https://www.novalon.cn"
]
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
export function WebsiteSchema() {
const schema = {
"@context": "https://schema.org",
"@type": "WebSite",
"name": "四川睿新致远科技有限公司",
"url": "https://www.novalon.cn",
"potentialAction": {
"@type": "SearchAction",
"target": "https://www.novalon.cn/search?q={search_term_string}",
"query-input": "required name=search_term_string"
}
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
export function ServiceSchema() {
const schema = {
"@context": "https://schema.org",
"@type": "Service",
"serviceType": "企业数字化转型服务",
"provider": {
"@type": "Organization",
"name": "四川睿新致远科技有限公司"
},
"description": "提供软件开发、云计算、数据分析、信息安全等一站式数字化转型解决方案",
"areaServed": {
"@type": "Country",
"name": "China"
}
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
+4 -4
View File
@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-all duration-200 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-2 focus-visible:ring-[#1C1C1C] focus-visible:ring-offset-2 focus-visible:ring-offset-white",
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-all duration-200 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-2 focus-visible:ring-[#1C1C1C] focus-visible:ring-offset-2 focus-visible:ring-offset-white min-h-[44px] min-w-[44px] touch-manipulation",
{
variants: {
variant: {
@@ -23,10 +23,10 @@ const buttonVariants = cva(
"text-[#1C1C1C] underline-offset-4 hover:underline hover:text-[#C41E3A]",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
default: "h-11 px-4 py-2",
sm: "h-9 rounded-md px-3 text-xs",
lg: "h-12 rounded-lg px-6 text-base",
icon: "h-10 w-10",
icon: "h-11 w-11",
},
},
defaultVariants: {
+1 -1
View File
@@ -28,7 +28,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
id={inputId}
data-slot="input"
className={cn(
"file:text-foreground placeholder:text-[#8C8C8C] selection:bg-[#1C1C1C] selection:text-white h-10 w-full min-w-0 rounded-lg border border-[#E5E5E5] bg-[#FAFAFA] px-4 py-2 text-base text-[#1C1C1C] shadow-sm transition-all duration-300 outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"file:text-foreground placeholder:text-[#8C8C8C] selection:bg-[#1C1C1C] selection:text-white h-12 w-full min-w-0 rounded-lg border border-[#E5E5E5] bg-[#FAFAFA] px-4 py-3 text-base text-[#1C1C1C] shadow-sm transition-all duration-300 outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 min-h-[44px] touch-manipulation",
"focus-visible:border-[#1C1C1C] focus-visible:ring-2 focus-visible:ring-[#1C1C1C]/50 focus-visible:shadow-lg focus-visible:shadow-[#1C1C1C]/20",
"hover:border-[#3D3D3D]",
error && "border-[#C41E3A] focus-visible:border-[#C41E3A] focus-visible:ring-[#C41E3A]/50",