构建多语言计算器平台的技术实践

59 阅读4分钟

在当今全球化的互联网环境中,多语言支持已成为现代 Web 应用的必备功能。本文将深入分享我们如何构建 Free Calculators 这个多语言计算器平台的技术实践,涵盖从技术栈选择到性能优化的完整解决方案。

技术栈概览

我们的平台采用了现代化的技术栈,确保高性能和优秀的用户体验:

核心技术

  • Next.js 15 - 最新的 React 全栈框架,支持 App Router
  • React 19 - 最新的 React 版本,带来更好的性能和开发体验
  • TypeScript - 严格的类型检查,提高代码质量和开发效率
  • Tailwind CSS 4 - 原子化 CSS 框架,快速构建响应式界面

国际化解决方案

  • next-intl - 专业的 Next.js 国际化库
  • 支持 12 种语言 - 英语、中文、日语、韩语、法语、德语、西班牙语、葡萄牙语、俄语、阿拉伯语、印地语、意大利语

性能与监控

  • Sentry - 错误监控和性能追踪
  • Google Analytics - 用户行为分析
  • Microsoft Clarity - 用户体验分析
  • Supabase - 后端数据存储

国际化实现详解

1. 路由结构设计

我们采用了 [locale] 动态路由结构,支持 SEO 友好的 URL:

// src/i18n/routing.ts
export const routing = defineRouting({
  locales: [
    'en',
    'zh',
    'ja',
    'ko',
    'fr',
    'de',
    'es',
    'pt',
    'ru',
    'ar',
    'hi',
    'it',
  ],
  defaultLocale: 'en',
  localePrefix: 'as-needed', // 默认语言不需要前缀
  localeDetection: true,
  pathnames: {
    '/': '/',
    '/finance': '/finance',
    '/math/basic-calculator': '/math/basic-calculator',
    // ... 更多路径配置
  },
});

2. 翻译文件管理

翻译文件统一存放在 messages/ 目录下,每个语言对应一个 JSON 文件:

messages/
├── en.json      # 英语(默认)
├── zh.json      # 中文
├── ja.json      # 日语
├── ko.json      # 韩语
├── fr.json      # 法语
├── de.json      # 德语
├── es.json      # 西班牙语
├── pt.json      # 葡萄牙语
├── ru.json      # 俄语
├── ar.json      # 阿拉伯语
├── hi.json      # 印地语
└── it.json      # 意大利语

3. 翻译文件结构

我们采用了嵌套的 JSON 结构来组织翻译内容:

{
  "nav": {
    "siteName": "Free Online Calculators",
    "home": "Home",
    "calculators": "Calculators"
  },
  "Home": {
    "title": "Free Online Calculator – Fast & Easy Math Tools",
    "description": "Use our free online calculator for quick math, percentages, and conversions."
  },
  "common": {
    "calculate": "Calculate",
    "clear": "Clear",
    "result": "Result"
  }
}

4. 中间件配置

使用 next-intl 的中间件来处理语言检测和重定向:

// src/middleware.ts
import createMiddleware from 'next-intl/middleware';
import { routing } from '@/i18n/routing';

export default createMiddleware(routing);

export const config = {
  matcher: '/((?!api|trpc|_next|_vercel|.*\\..*).*)',
};

SEO 优化策略

1. 静态站点生成 (SSG)

我们使用 Next.js 的静态生成功能,为每种语言生成静态页面:

// src/app/[locale]/layout.tsx
export const dynamic = 'force-static';

export function generateStaticParams() {
  return routing.locales
    .filter(locale => locale !== routing.defaultLocale)
    .map(locale => ({ locale }));
}

2. 元数据生成

为每个页面生成 SEO 友好的元数据:

export async function generateMetadata({
  params,
}: {
  params: Promise<{ locale: string }>;
}): Promise<Metadata> {
  const { locale } = await params;
  const t = await getTranslations({ locale, namespace: 'Home' });

  return {
    title: t('title'),
    description: t('description'),
    openGraph: {
      title: t('title'),
      description: t('description'),
      locale: locale,
    },
  };
}

3. 站点地图生成

我们开发了自动化的站点地图生成脚本,支持多语言:

// scripts/generate-sitemap.mjs
const generateSitemap = async () => {
  const sitemap = [];

  for (const locale of locales) {
    for (const calculator of calculators) {
      const url = `${SITE_URL}/${locale}${calculator.path}`;
      sitemap.push({
        url,
        lastmod: new Date().toISOString(),
        changefreq: 'weekly',
        priority: 0.8,
      });
    }
  }

  return sitemap;
};

性能优化实践

1. 图片优化

配置了多种图片格式和尺寸:

// next.config.ts
images: {
  formats: ['image/avif', 'image/webp'],
  domains: ['freecalculators.app'],
  deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
  imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
}

2. 缓存策略

实现了分层的缓存策略:

async headers() {
  return [
    // 静态资源使用强缓存
    {
      source: '/(.*).(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot)',
      headers: [{
        key: 'Cache-Control',
        value: 'public, max-age=31536000, immutable',
      }],
    },
    // 页面使用协商缓存
    {
      source: '/(.*)',
      headers: [{
        key: 'Cache-Control',
        value: 'public, max-age=0, must-revalidate',
      }],
    },
  ];
}

3. 代码分割

使用动态导入和 React.lazy 进行代码分割:

const LazyComponent = React.lazy(() => import('./HeavyComponent'));

function MyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

用户体验设计

1. 响应式设计

使用 Tailwind CSS 实现移动端优先的响应式设计:

// 移动端优先的响应式布局
<div className="flex flex-col md:flex-row gap-4">
  <div className="w-full md:w-1/2">
    {/* 计算器界面 */}
  </div>
  <div className="w-full md:w-1/2">
    {/* 结果展示 */}
  </div>
</div>

2. 无障碍性支持

添加了完整的无障碍性支持:

<button
  aria-label={t('common.calculate')}
  aria-describedby="calculator-help"
  className="bg-blue-600 text-white px-4 py-2 rounded"
>
  {t('common.calculate')}
</button>

3. 错误处理

实现了全局错误边界和用户友好的错误提示:

// src/components/ErrorBoundary.tsx
export default class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    console.error('Error caught by boundary:', error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <ErrorFallback />;
    }

    return this.props.children;
  }
}

开发工具链

1. 代码质量

配置了完整的代码质量工具:

// package.json
{
  "scripts": {
    "lint": "next lint",
    "lint:fix": "next lint --fix",
    "type-check": "tsc --noEmit",
    "format": "prettier --write .",
    "format:check": "prettier --check ."
  }
}

2. 翻译管理

开发了自动化翻译管理脚本:

// scripts/translation-manager.js
const addMissingTranslations = async () => {
  const baseTranslations = await loadTranslations('en');
  const allLocales = await getAllLocales();

  for (const locale of allLocales) {
    const existingTranslations = await loadTranslations(locale);
    const missingKeys = findMissingKeys(baseTranslations, existingTranslations);

    if (missingKeys.length > 0) {
      await addMissingKeys(locale, missingKeys);
    }
  }
};

部署和监控

1. Vercel 部署

使用 Vercel 进行部署,配置了环境变量和域名重定向:

// vercel.json
{
  "env": {
    "NEXT_PUBLIC_SUPABASE_URL": "@supabase-url",
    "NEXT_PUBLIC_SUPABASE_ANON_KEY": "@supabase-anon-key"
  },
  "redirects": [
    {
      "source": "/(.*)",
      "destination": "https://www.freecalculators.app/$1",
      "permanent": true
    }
  ]
}

2. 性能监控

集成了 Sentry 进行错误监控和性能追踪:

// next.config.ts
export default withSentryConfig(withNextIntl(nextConfig), {
  org: 'my-projects-pd',
  project: 'free-calculators',
  widenClientFileUpload: true,
  disableLogger: true,
  automaticVercelMonitors: true,
});

技术亮点总结

1. 多语言支持

  • 支持 12 种语言,覆盖全球主要市场
  • SEO 友好的 URL 结构
  • 自动语言检测和重定向

2. 性能优化

  • 静态站点生成,极快的加载速度
  • 图片优化和懒加载
  • 智能缓存策略

3. 开发体验

  • TypeScript 严格类型检查
  • 自动化翻译管理
  • 完整的错误监控

4. 用户体验

  • 响应式设计,支持所有设备
  • 无障碍性支持
  • 直观的用户界面

最佳实践建议

  1. 国际化设计:从项目开始就考虑多语言支持,避免后期重构
  2. 性能优先:使用静态生成和 CDN 加速
  3. 用户体验:注重无障碍性和响应式设计
  4. 监控完善:建立完整的错误监控和性能追踪体系
  5. 自动化:使用脚本自动化翻译管理和部署流程

结语

构建多语言 Web 应用需要综合考虑技术选型、性能优化、用户体验等多个方面。通过合理的技术架构和完善的开发流程,我们成功构建了一个高性能、多语言的计算器平台。

希望这篇文章能对正在构建多语言 Web 应用的开发者有所帮助。如果你有任何问题或建议,欢迎在评论区交流讨论。


项目链接www.freecalculators.app 技术栈:Next.js 15, React 19, TypeScript, Tailwind CSS, next-intl