Co-Pilot / 辅助式
更新于 24 days ago

shipfree

Rrevokslab
1.6k
revokslab/shipfree
78
Agent 评分

💡 摘要

ShipFree是一个现代化的运输解决方案,简化了运输过程并支持国际化。

🎯 适合人群

寻找运输解决方案的电子商务企业需要可定制运输模板的开发者希望优化运输流程的初创企业提供运输服务的自由职业者寻求经济高效运输选项的小型企业

🤖 AI 吐槽:看起来很能打,但别让配置把人劝退。

安全分析中风险

风险:Medium。建议检查:是否发起外网请求(SSRF/数据外发)。以最小权限运行,并在生产环境启用前审计代码与依赖。

⚡ ShipFree V2 - Revamping

Hi there! 👋

ShipFree is a free alternative to ShipFast, designed to simplify and optimize your shipping process. It’s built using modern web technologies like Next.js, Bun, Stripe, Drizzle ORM, Postgres and Tailwindcss.

Features

  • SEO Optimization
  • User authentication with Better-Auth
  • Stripe, Polar, Autumn Billing, Dodo Payments, Commet and Creem integration
  • Email messaging via Resend, Postmark, Plunk, and Nodemailer
  • Modern UI built with Next.js, TailwindCSS, and BaseUI
  • Bun as runtime and package manager
  • Drizzle ORM and Postgres for database operations
  • Internationalization (i18n) with next-intl supporting English, French, and Spanish

Docs

For full documentation, visit: ShipFree Docs

Code of Conduct

Please read our Code of Conduct before contributing.

Contributing

For people who want to contribute, please refer to CONTRIBUTING.md.

Internationalization (i18n) Navigation

ShipFree includes internationalization support using next-intl with automatic locale routing. The template supports English (en), French (fr), and Spanish (es) out of the box.

Navigation Components and Hooks

The i18n/navigation.ts file exports internationalized versions of Next.js navigation components and hooks that automatically handle locale prefixes:

  • Link - Internationalized Link component that automatically prefixes routes with the current locale
  • redirect - Server-side redirect function that preserves locale
  • usePathname - Hook that returns the pathname without the locale prefix
  • useRouter - Hook for programmatic navigation with locale support

Usage Examples

Using the Link Component

import { Link } from '@/i18n/navigation' // Automatically includes locale prefix (e.g., /en/about, /fr/about) <Link href="/about">About</Link> // Switch to a different locale <Link href="/about" locale="fr">À propos</Link>

Using Navigation Hooks

'use client' import { useRouter, usePathname } from '@/i18n/navigation' import { useLocale } from 'next-intl' export function MyComponent() { const router = useRouter() const pathname = usePathname() const locale = useLocale() // Navigate to a route (automatically includes locale) const handleClick = () => { router.push('/dashboard') } // Switch locale for current page const switchLanguage = (newLocale: string) => { router.replace(pathname, { locale: newLocale }) } return ( <div> <p>Current locale: {locale}</p> <p>Current pathname: {pathname}</p> <button onClick={handleClick}>Go to Dashboard</button> <button onClick={() => switchLanguage('fr')}>Switch to French</button> </div> ) }

Using Translations

// Server Component import { getTranslations } from 'next-intl/server' export default async function ServerPage() { const t = await getTranslations('MyPage') return <h1>{t('title')}</h1> } // Client Component 'use client' import { useTranslations } from 'next-intl' export default function ClientPage() { const t = useTranslations('MyPage') return <h1>{t('title')}</h1> }

Adding New Locales

To add a new locale:

  1. Add the locale to i18n/routing.ts:

    locales: ['en', 'fr', 'es', 'de'], // Add 'de' for German
  2. Create a translation file in messages/:

    // messages/de.json { "PRICING": "Preise" }
  3. Update the localeNames object in components/language-switcher.tsx:

    const localeNames: Record<string, string> = { en: 'English', fr: 'Français', es: 'Español', de: 'Deutsch', // Add German }

Route Structure

All routes are automatically prefixed with the locale:

  • / or /en → English homepage
  • /fr → French homepage
  • /es → Spanish homepage
  • /en/about → English about page
  • /fr/about → French about page

The default locale (en) uses the as-needed prefix strategy, meaning it doesn't show the locale prefix in the URL when it's the default language.

Removing Premium Purchase Feature

This template includes a premium purchase feature that allows users to buy the Premium version of ShipFree. This feature is completely isolated from the template's payment system and can be easily removed if you don't need it.

What is the Premium Purchase Feature?

The premium purchase feature is used to sell the Premium template itself ($90 one-time payment). It includes:

  • Stripe Checkout integration for one-time payments
  • Success page that collects GitHub email and Twitter handle
  • Discord invite link display after purchase
  • Client-side purchase tracking via localStorage

Important: This is separate from the template's built-in payment system (Stripe, Polar, Lemon Squeezy) which is used by your application to accept payments from your customers.

How to Remove

To completely remove the premium purchase feature:

  1. Delete the following folders:

    • app/api/premium-purchase/
    • app/api/webhooks/premium-purchase/ (if created)
    • app/[locale]/(site)/premium-purchase/
  2. Delete the following files:

    • lib/premium-purchase.ts
    • lib/premium-purchase/hooks.ts
    • app/[locale]/(site)/pricing/premium-button.tsx
  3. Update app/[locale]/(site)/pricing.tsx:

    • Remove the import: import { PremiumButton } from './pricing/premium-button'
    • Replace <PremiumButton /> with a regular button or remove the button handler
    • Look for the comment: // Premium template purchase - can be removed if not needed
  4. Remove environment variables from config/env.ts:

    • Remove all variables with PREMIUM_PURCHASE_ prefix:
      • PREMIUM_PURCHASE_STRIPE_SECRET_KEY (server)
      • PREMIUM_PURCHASE_STRIPE_PRICE_ID (server)
      • PREMIUM_PURCHASE_STRIPE_WEBHOOK_SECRET (server, optional)
      • NEXT_PUBLIC_PREMIUM_PURCHASE_STRIPE_PUBLISHABLE_KEY (client)
      • NEXT_PUBLIC_PREMIUM_PURCHASE_DISCORD_INVITE_LINK (client)
  5. Remove from .env file:

    • Remove all PREMIUM_PURCHASE_* environment variables
  6. Remove webhook endpoint (if configured):

    • Remove the webhook endpoint from your Stripe Dashboard pointing to /api/webhooks/premium-purchase

After removal, the template's payment functionality (for your customers) will continue to work normally. The premium purchase feature is completely decoupled and does not affect any other features.


Cooked for you with ❤️ by Revoks

五维分析
清晰度8/10
创新性7/10
实用性9/10
完整性8/10
可维护性7/10
优缺点分析

优点

  • 支持多种语言以满足国际用户
  • 与多种支付系统集成
  • 使用流行框架构建的现代用户界面
  • 易于定制和扩展

缺点

  • 需要熟悉现代网络技术
  • 为新语言环境可能需要额外设置
  • 高级功能是独立的,可能会让用户困惑
  • 依赖多个外部服务

相关技能

pytorch

S
toolCode Lib / 代码库
92/ 100

“它是深度学习的瑞士军刀,但祝你好运能从47种安装方法里找到那个不会搞崩你系统的那一个。”

agno

S
toolCode Lib / 代码库
90/ 100

“它承诺成为智能体领域的Kubernetes,但得看开发者有没有耐心学习又一个编排层。”

nuxt-skills

S
toolCo-Pilot / 辅助式
90/ 100

“这本质上是一份组织良好的小抄,能把你的 AI 助手变成一只 Nuxt 框架的复读机。”

免责声明:本内容来源于 GitHub 开源项目,仅供展示和评分分析使用。

版权归原作者所有 revokslab.