Website Configuration
Core settings for your MinuteShip website
The main configuration file that contains the core settings for the website.
MinuteShip has already set up the default core settings for you, and you can customize the core settings in this file src/config/website.ts.
src/config/website.ts
export const websiteConfig: WebsiteConfig = {
ui: {
// UI settings
},
metadata: {
// Metadata settings
},
social: {
// Social media settings
},
auth: {
// Auth settings
},
blog: {
// Blog settings
},
docs: {
// Docs settings
},
mail: {
// Mail settings
},
newsletter: {
// Newsletter settings
},
notification: {
// Notification settings
},
cache: {
// Cache settings
},
storage: {
// Storage settings
},
payment: {
// Payment settings
},
};
UI
Controls the appearance of your website.
Mode
Controls the light/dark mode settings:
| Property | Type | Description |
|---|---|---|
defaultMode | 'light' | 'dark' | 'system' | Sets the default display mode |
enableSwitch | boolean | When true, allows users to toggle between light/dark modes |
Example:
src/config/website.ts
ui: {
mode: {
defaultMode: 'system', // Choose from: light, dark, system
enableSwitch: true, // Allow users to switch modes
},
}
Metadata
Controls the metadata of your website. The metadata configuration consists of several subsections:
Basic Information
Defines the basic metadata for the website:
| Property | Type | Description |
|---|---|---|
name | string | Website name, used for branding |
title | string | Website title, used for browser tabs and SEO |
description | string | Website description, used for search engines and social media previews |
Example:
src/config/website.ts
metadata: {
// import { m } from '@/locale/paraglide/messages';
get name() { return m.site_name(); },
get title() { return m.site_title(); },
get description() { return m.site_description(); },
// ...
}
Images
Defines the images used for branding and social sharing:
| Property | Type | Description |
|---|---|---|
ogImage | string | URL to the Open Graph image used for social media previews |
logoLight | string | URL to your logo image for light mode |
logoDark | string | URL to your logo image for dark mode |
Example:
src/config/website.ts
metadata: {
images: {
ogImage: '/og.png', // Open Graph image for social sharing
logoLight: '/logo.png', // Logo displayed in light mode
logoDark: '/logo-dark.png', // Logo displayed in dark mode
},
// ...
}
You can find more about customizing the images in the Metadata documentation.
Social Media
Configure links to your social media profiles. In MinuteShip, social is a top-level key in websiteConfig (not nested under metadata):
| Property | Type | Description |
|---|---|---|
github | string | URL to GitHub profile or repository |
twitter | string | URL to Twitter/X profile |
blueSky | string | URL to Bluesky profile |
discord | string | URL to Discord server |
mastodon | string | URL to Mastodon profile |
linkedin | string | URL to LinkedIn profile |
youtube | string | URL to YouTube channel |
facebook | string | URL to Facebook page |
instagram | string | URL to Instagram profile |
tiktok | string | URL to TikTok profile |
telegram | string | URL to Telegram group or channel |
Example:
src/config/website.ts
social: {
github: 'https://github.com/YourOrganization',
twitter: 'https://x.com/YourHandle',
discord: 'https://discord.gg/your-invitation-code',
youtube: 'https://youtube.com/@YourChannel',
}
These social media links are used by the Social Media Configuration to generate the appropriate links across the website.
Auth
Configure authentication options for your website:
| Property | Type | Description |
|---|---|---|
enable | boolean | When true, enables authentication |
enableGoogleLogin | boolean | When true, enables Google login |
enableCredentialLogin | boolean | When true, enables credential login |
enableDeleteAccount | boolean | When true, allows users to delete their account |
Example:
src/config/website.ts
auth: {
enable: true,
enableGoogleLogin: true,
enableCredentialLogin: true,
enableDeleteAccount: true,
}
MinuteShip supports Google OAuth and email/password authentication. You can selectively disable specific providers using these configuration options:
- Set
enableGoogleLogintofalseto remove Google login option - Set
enableCredentialLogintofalseto remove credential login
Warning
Note: Please ensure at least one login method is enabled, otherwise users will not be able to log in.
You can find more about authentication options in the Authentication documentation.
Blog
Configure the blog functionality:
| Property | Type | Description |
|---|---|---|
enable | boolean | Whether to enable the blog or not, default is true |
paginationSize | number | Number of posts to display per page |
Example:
src/config/website.ts
blog: {
enable: true,
paginationSize: 6,
}
Note
If you don't need the blog functionality, you can set
enabletofalse, then the blog menus will not be shown in the navbar and footer, and the blog related pages will not be included in the sitemap.
You can find more about blog configuration in the Blog documentation.
Docs
Configure the documentation section:
| Property | Type | Description |
|---|---|---|
enable | boolean | Whether to enable the docs section, default is true |
Example:
src/config/website.ts
docs: {
enable: true,
},
Note
If you don't need the docs section, set
enabletofalse./docsand/docs/<slug>then return 404, the docs menus disappear from the navbar and footer, and docs URLs are left out of the sitemap.
Documentation pages are Markdown files in content/docs, and the file name is the slug (env.md → /docs/env). Keep file names flat, because the page route /docs/$slug matches a single path segment. Every file needs title, description, group, and order frontmatter:
---
title: Environment Variables
description: Configure environment variables
group: Getting Started
order: 5
---
order is sorted across every page before grouping, so use unique numbers for the whole set instead of restarting per group. Add <slug>.zh.md for a Chinese version; a page without a translation falls back to the default locale. Internal links are not localized automatically, so write /docs/env in English pages and /zh/docs/env in Chinese pages.
Run pnpm content:build before shipping so the generated content collection is current.
Configure email services:
| Property | Type | Description |
|---|---|---|
enable | boolean | Whether to enable email functionality, default is true |
provider | 'cloudflare' | 'resend' | Email service provider |
fromEmail | string | Contact email for sending emails |
supportEmail | string | Contact email for receiving emails |
Example:
mail: {
enable: true,
provider: 'cloudflare',
fromEmail: 'contact@example.com',
supportEmail: 'support@example.com',
}
You can find more about mail configuration in the Email documentation.
Newsletter
Configure newsletter services:
| Property | Type | Description |
|---|---|---|
enable | boolean | Whether to enable the newsletter or not, default is true |
provider | 'resend' | 'beehiiv' | 'mailcheap' | Newsletter service provider |
autoSubscribeAfterSignUp | boolean | Whether to automatically subscribe users after sign up |
Example:
src/config/website.ts
newsletter: {
enable: true,
provider: 'resend',
autoSubscribeAfterSignUp: true,
}
Note
If you don't need the newsletter functionality, you can set
enabletofalse, then the subscription status will not be shown in the notification settings page.
You can find more about newsletter configuration in the Newsletter documentation. To use MailCheap, set provider to 'mailcheap' and configure MAILCHEAP_API_KEY and MAILCHEAP_NEWSLETTER_ID; select the MailCheap tab in Newsletter Setup.
Cache
Configure server-side cache:
| Property | Type | Description |
|---|---|---|
enable | boolean | Whether to enable the cache or not, default is true |
provider | 'kv' | Cache provider (currently only Cloudflare KV is supported) |
Example:
src/config/website.ts
cache: {
enable: true,
provider: 'kv',
}
Note
If you don't need server-side caching, you can set
enabletofalse. Cache helpers will skip KV and call the original fetcher directly.
You can find more about cache configuration in the Cache documentation.
Storage
Configure file storage:
| Property | Type | Description |
|---|---|---|
enable | boolean | Whether to enable the storage or not, default is true |
provider | 'r2' | Storage provider (currently only R2 is supported) |
maxFileSize | number | Maximum file size in bytes |
allowedTypes | string[] | Allowed file extensions, such as ['.jpg', '.png', 'webp']; MIME types are not matched |
userFilesFolder | string | Folder name for user uploaded files |
Example:
src/config/website.ts
storage: {
enable: true,
provider: 'r2',
maxFileSize: DEFAULT_MAX_FILE_SIZE,
allowedTypes: DEFAULT_ALLOWED_TYPES,
userFilesFolder: DEFAULT_USER_FILES_FOLDER,
}
An empty allowedTypes array allows every extension. Entries may include the leading dot or omit it, but values such as image/webp do not match because validation compares file extensions rather than MIME types.
Note
If you don't need the storage functionality, you can set
enabletofalse, then the update avatar functionality in the settings page will not be available.
You can find more about storage configuration in the Storage documentation.
Notification
Configure notification services:
| Property | Type | Description |
|---|---|---|
enable | boolean | Whether to enable notification functionality, default is true |
provider | 'discord' | 'feishu' | Notification provider |
Example:
src/config/website.ts
notification: {
enable: true,
provider: 'discord',
}
You can find more about notification configuration in the Notification documentation.
Payment
Configure payment processing services. The payment section includes both the payment provider settings and price plan configuration:
| Property | Type | Description |
|---|---|---|
enable | boolean | Derived from VITE_PAYMENT_PROVIDER; empty/unset disables payments |
provider | 'stripe' | 'creem' | 'waffo' | Payment processor |
price | object | Price plans configuration (see below) |
Example:
src/config/website.ts
payment: {
enable: isPaymentEnabled,
provider: isPaymentEnabled ? paymentProvider : undefined,
price: {
plans: {
// ... price plans
},
},
}
You can find more about payment configuration in the Payment documentation.
paymentProvider, isPaymentEnabled, and priceIds are computed from clientEnv at the top of this file. Select stripe, creem, or waffo using VITE_PAYMENT_PROVIDER and supply that provider's VITE_* price/product IDs. The current template sets no default trialPeriodDays; configure trials for the chosen provider/product.
Price Plans
Each price plan in the payment.price.plans object can have the following properties:
| Property | Type | Description |
|---|---|---|
id | string | Unique identifier for the plan |
name | string? | Display name of the plan |
description | string? | Description of the plan features |
features | string[]? | List of features included in this plan |
limits | string[]? | List of limits for this plan |
prices | Price[] | List of price options for the plan (monthly, yearly, one-time, etc.) |
isFree | boolean | Whether this is a free plan |
isLifetime | boolean | Whether this is a lifetime (one-time payment) plan |
popular | boolean? | Whether to highlight this plan as popular |
disabled | boolean? | Whether to disable this plan in UI |
The prices array contains objects with the following structure:
| Property | Type | Description |
|---|---|---|
type | 'subscription' | 'one_time' | Type of payment (subscription or one-time) |
priceId | string | Price/product ID for the configured payment provider |
amount | number | Amount in minor units (e.g. 990 = USD 9.90) |
currency | string | Currency code (e.g., USD) |
interval | 'month' | 'year'? | Billing interval for recurring payments |
trialPeriodDays | number? | Free trial period in days |
allowPromotionCode | boolean? | Whether to allow promotion code for this price |
disabled | boolean? | Whether to disable this price in UI |
MinuteShip uses three price plans by default: Free plan, Pro subscription plan (monthly/yearly), and Lifetime plan (one-time payment), as shown in the website configuration:
src/config/website.ts
price: {
plans: {
free: {
id: 'free',
prices: [],
isFree: true,
isLifetime: false,
},
pro: {
id: 'pro',
prices: [
{
type: 'subscription',
priceId: priceIds.proMonthly,
amount: 990,
currency: 'USD',
interval: 'month',
},
{
type: 'subscription',
priceId: priceIds.proYearly,
amount: 9900,
currency: 'USD',
interval: 'year',
},
],
isFree: false,
isLifetime: false,
popular: true,
},
lifetime: {
id: 'lifetime',
prices: [
{
type: 'one_time',
priceId: priceIds.lifetime,
amount: 19900,
currency: 'USD',
allowPromotionCode: true,
},
],
isFree: false,
isLifetime: true,
},
},
},
Warning
When to set price plans or prices as disabled?
Set a price plan to
disabled: truewhen the price plan is not available for new customers, but you need to keep it for existing users who have already purchased it.Set a price to
disabled: truewhen that specific price is not available anymore, but existing subscribers on that price should still be able to see it in the billing page.
You can find more about price configuration in the Payment documentation.
Next Steps
Now that you understand the website configuration, explore these related topics:
- Navbar Configuration: Configure the navigation menu in the header
- Footer Configuration: Configure the links in the website footer
- Payment Integration: Set up payment processing
- Sidebar Configuration: Configure the navigation menu for dashboard