diff --git a/apps/web/app/messages b/apps/web/app/messages
new file mode 100644
index 0000000000..48f1e954d3
--- /dev/null
+++ b/apps/web/app/messages
@@ -0,0 +1,390 @@
+{
+ "../ui/analytics/events": {
+ "filter": "Filter",
+ "download-as-csv": "Download as CSV",
+ "upgrade-business-plan-csv-downloads": "Upgrade to our Business Plan to enable CSV downloads for events in your workspace."
+ },
+ "../ui/analytics": {
+ "no-data-available": "No data available",
+ "no-url-configured": "No URL configured",
+ "download-as-csv": "Download as CSV"
+ },
+ "../ui/workspaces": {
+ "workspace-level-conversion-tracking": "Workspace-level conversion tracking",
+ "enable-conversion-tracking-future-links": "Enable conversion tracking for all future links in this workspace. This only affects links made with the link builder.",
+ "conversion-tracking-business-plans-only": "You can only enable conversion tracking on Business plans and above.",
+ "workspace-logo": "Workspace Logo",
+ "workspace-logo-description": "This is your workspace's logo on {processEnvNextPublicAppName}.",
+ "image-upload-recommendations": "Square image recommended. Accepted file types: .png, .jpg. Max file size: 2MB.",
+ "save-changes-button": "Save changes",
+ "upgrade-required": "Upgrade required",
+ "email-contact-panic": "panic@thedis.co",
+ "add-email-button": "Add email",
+ "pro-plan-invite-teammates_component0": "Learn more",
+ "pro-plan-invite-teammates": " saved. You'll need a pro plan to invite teammates. {component0}",
+ "workspace-name": "Workspace Name",
+ "company-name": "Acme, Inc.",
+ "workspace-slug": "Workspace Slug",
+ "app-domain": "app.{processEnvNextPublicAppDomain}",
+ "workspace-id": "acme",
+ "create-workspace": "Create workspace"
+ },
+ "../ui/auth/login": {
+ "continue-with-github": "Continue with Github",
+ "email-address": "panic@thedis.co",
+ "password-optional": "Password (optional)",
+ "continue-with-password-or-email": "Continue with {passwordPasswordEmail}",
+ "forgot-password": "Forgot password?"
+ },
+ "../ui/account": {
+ "subscribed-to-product-updates": "Subscribed to product updates",
+ "user-id-label": "Your User ID",
+ "account-identifier-description": "This is your unique account identifier on Dub."
+ },
+ "../ui/modals/link-builder": {
+ "link": "(link)",
+ "failed-to-load-templates": "Failed to load templates",
+ "utm-templates": "UTM Templates",
+ "no-templates-found": "No templates found",
+ "link-password": "Link Password",
+ "restrict-access-encrypt-password": "Restrict access to your short links by encrypting it with a password.",
+ "quick-access-instruction_component0": "P",
+ "quick-access-instruction": "Press {component0} to open this quickly",
+ "shortcut-key-p": "P",
+ "password-label": "Password",
+ "create-password": "Create password",
+ "remove-password": "Remove password",
+ "cancel": "Cancel"
+ },
+ "../ui/modals": {
+ "template-name": "Template Name",
+ "new-template-title": "New Template",
+ "parameters-label": "Parameters",
+ "create-template-action": "Create template",
+ "learn-more": "Learn more",
+ "confirm-archive-unarchive": "Confirm {propsArchivedUnarchiveArchive}",
+ "api-key-created": "API Key Created",
+ "api-key-security-notice": "For security reasons, we will only show you the key once. Please copy and store it somewhere safe.",
+ "api-key-label": "API key",
+ "done-button": "Done",
+ "delete-shortlink": "Delete {shortlink}",
+ "warning-deleting-link-analytics": "Warning: Deleting this link will remove all of its analytics. This action cannot be undone – proceed with caution.",
+ "verify-type-shortlink": "To verify, type {component0} below",
+ "confirm-delete": "Confirm delete",
+ "workspace-logo": "Workspace logo",
+ "workspace-removal-confirmation": "{inviteThisWillRevokeSessionUserEmailEmailYouReAboutToLeaveThisWillRemove}{component0}{inviteSInvitationToJoinYourWorkspaceSessionUserEmailEmailYouWillLoseAllAccessToThisWorkspaceFromYourWorkspace} Are you sure you want to continue?",
+ "confirm-button": "Confirm",
+ "qr-code-title": "QR Code",
+ "qr-code-custom-design-description": "Set a custom QR code design to improve click-through rates.",
+ "qr-code-quick-open-instruction_component0": "Q",
+ "qr-code-quick-open-instruction": "Press {component0} to open this quickly",
+ "qr-code-quick-open-key": "Q",
+ "qr-code-preview-title": "QR Code Preview",
+ "qr-code-customization-brand-description": "Customize your QR code to fit your brand.",
+ "qr-code-logo-label": "Logo",
+ "qr-code-logo-display-description": "Display your logo in the center of the QR code.",
+ "qr-code-logo-pro-plan-requirement": "You need to be on the Pro plan and above to customize your QR Code logo.",
+ "qr-code-color-label": "QR Code Color",
+ "button-cancel": "Cancel",
+ "button-save-changes": "Save changes",
+ "button-download-svg": "Download SVG",
+ "button-download-png": "Download PNG",
+ "button-download-jpeg": "Download JPEG",
+ "button-copy-image": "Copy Image",
+ "button-copy-url": "Copy URL",
+ "bitly-logo": "Bitly logo",
+ "import-your-bitly-links": "Import Your Bitly Links",
+ "easily-import-bitly-links": "Easily import all your existing Bitly links into {processEnvNextPublicAppName} with just a few clicks.",
+ "connecting-to-bitly": "Connecting to Bitly",
+ "domains-header": "Domains",
+ "tags-found-import-all": "{tagsLength} tags found. Import all?",
+ "no-bitly-groups-warning": "It looks like you don't have any Bitly groups with custom domains (non bit.ly domains).",
+ "confirm-import": "Confirm import",
+ "sign-in-different-bitly-account": "Sign in to a different Bitly account?",
+ "sign-in-with-bitly": "Sign in with Bitly",
+ "bitly-logo-duplicate": "Bitly logo",
+ "read-the-guide": "Read the guide"
+ },
+ "../ui/oauth-apps": {
+ "client-id": "Client ID",
+ "client-secret-label": "Client Secret",
+ "client-secret-warning": "Be sure to copy your client secret. You won’t be able to see it again.",
+ "client-secret-label-duplicate": "Client Secret",
+ "application-name": "Application name",
+ "my-app-name": "My App",
+ "application-slug": "Application slug",
+ "description": "Description",
+ "add-description-placeholder": "Add a description",
+ "overview": "Overview",
+ "my-awesome-integration-title": "## My Awesome Integration",
+ "screenshots": "Screenshots",
+ "developer-name": "Developer name",
+ "acme-inc": "Acme Inc.",
+ "website-url": "Website URL",
+ "acme-website-url": "https://acme.com"
+ },
+ "../ui/webhooks": {
+ "response-message": "Response",
+ "http-status-code": "HTTP status code",
+ "request-message": "Request",
+ "back-to-webhooks": "Back to webhooks",
+ "copy-webhook-id": "Copy Webhook ID",
+ "send-test-event": "Send test event",
+ "delete-webhook": "Delete webhook"
+ },
+ "../ui/domains": {
+ "provisioned-by-dub": "Provisioned by Dub",
+ "learn-more": "Learn more",
+ "clicks": "clicks",
+ "dns-setup-success_component0": "Learn more.",
+ "dns-setup-success": "Good news! Your DNS records are set up correctly, but it can take some time for them to propagate globally. {component0}",
+ "link-settings": "Link Settings",
+ "edit-link": "Edit Link",
+ "qr-code": "QR Code",
+ "copy-link-id": "Copy Link ID",
+ "domain-settings": "Domain Settings",
+ "edit-domain": "Edit Domain",
+ "set-as-primary": "Set as Primary",
+ "transfer-domain": "Transfer",
+ "delete-domain": "Delete"
+ },
+ "../ui/links": {
+ "link-not-found": "Link Not Found",
+ "link-not-found-bummer-message": "Bummer! The link you are looking for does not exist. You either typed in the wrong URL or don't have access to this link.",
+ "no-links-yet": "No links yet"
+ },
+ "../ui/shared": {
+ "pro": "Pro"
+ },
+ "../ui/layout": {
+ "root-domain-links": "Root Domain Links"
+ },
+ "../ui/layout/sidebar": {
+ "payouts-title": " Payouts",
+ "upcoming-payouts": "Upcoming payouts",
+ "total-payouts": "Total payouts",
+ "connect-payouts": "Connect payouts"
+ },
+ "admin.dub.co/(dashboard)/components": {
+ "app-dub-co-login-link": "app.dub.co login link",
+ "partners-dub-co-login-link": "partners.dub.co login link",
+ "id": "ID",
+ "plan": "Plan",
+ "domains": "Domains",
+ "links": "Links",
+ "clicks": "Clicks"
+ },
+ "app.dub.co/embed/inline": {
+ "refer-and-earn": " Refer and earn",
+ "referral-link": "Referral link",
+ "powered-by": "Powered by",
+ "payouts": "Payouts"
+ },
+ "../emails": {
+ "referral-sale-notification": "You just made a {earningsInDollars} sale via your referral link",
+ "referral-sale-success": "You just made a {earningsInDollars} referral sale!",
+ "purchase-notification-with-referral": "Congratulations! Someone made a {component0} purchase on {component1} using your referral link ( {component2} ).",
+ "commission-receipt-notification": "Your received {component0} in commission for this sale and it will be included in your next payout.",
+ "view-sale-link": "View sale",
+ "new-workspace-api-key-created": "New Workspace API Key Created",
+ "new-workspace-api-key-created-whitespace": "New Workspace API Key Created",
+ "api-key-created-for-workspace_component1": "\"",
+ "api-key-created-for-workspace": "You've created a new API key for your Dub.co workspace {component0} with the name {component1} on {formatDateNewDateToString}.",
+ "token-type-info": "Since this is a {component0} token, it has",
+ "view-api-keys": "View API Keys",
+ "delete-api-key-instructions": "If you did not create this API key, you can {component0} from your account.",
+ "delete-this-key": "delete this key",
+ "webhook-failing-deliver": "Webhook is failing to deliver",
+ "webhook-failing-deliver-whitespace": "Webhook is failing to deliver",
+ "webhook-url-failed-deliver": "Your webhook {component0} has failed to deliver",
+ "webhook-disabled-after-failures": " times and will be disabled after {WEBHOOK_FAILURE_DISABLE_THRESHOLD} consecutive failures.",
+ "review-webhook-details": "Please review the webhook details and update the URL if necessary to restore functionality.",
+ "edit-webhook": "Edit Webhook",
+ "new-feedback-received": "New Feedback Received",
+ "dub-title": "Dub",
+ "new-feedback-received-multiline": "New Feedback Received",
+ "new-feedback-from-email": "New feedback from {component0}",
+ "failed-payment-attempt-notification": "{attemptCount,select,true{2nd } false{{attemptCount,select,true{3rd } false{}}}} Failed Payment for Dub.co",
+ "greeting-user": "Hey{userNameUserName}!",
+ "payment-failed-notification_component0": "$",
+ "payment-failed-notification_component2": "update your payment information",
+ "payment-failed-notification": "Your payment of {component0} for your Dub workspace {component1} has failed. Please {component2} using the link below:",
+ "update-payment-information": "Update payment information",
+ "customer-support-invitation": "If you have any questions, feel free to respond to this email – we're happy to help!"
+ },
+ "partners.dub.co/(auth)/(default)": {
+ "partner-label": "Partner",
+ "dub-technologies-inc": " Dub Technologies, Inc.",
+ "privacy-policy": "Privacy Policy",
+ "terms-of-service": "Terms of Service"
+ },
+ "[domain]/not-found": {
+ "link-not-found": "Link Not Found",
+ "link-not-exist-message": "This link does not exist. Please check the URL and try again.",
+ "create-free-branded-link": "Create Your Free Branded Link"
+ },
+ "partners.dub.co/(dashboard)/settings/payouts": {
+ "payout-details": "Payout details",
+ "invoice-details": "Invoice details",
+ "view-all": "View all",
+ "close-button": "Close"
+ },
+ "app.dub.co/(auth)/login": {
+ "sign-in-dub-account": "Sign in to your Dub account",
+ "dont-have-account-sign-up-link_component0": "Sign up",
+ "dont-have-account-sign-up-link": "Don't have an account? {component0}"
+ },
+ "app.dub.co/(auth)/auth/saml": {
+ "saml-authentication": "SAML Authentication",
+ "app-name-saml-verification": "{APP_NAME} is verifying your identity via SAML. This might take a few seconds..."
+ },
+ "partners.dub.co/(auth)/(custom)/[programSlug]/login": {
+ "framer-logo": "Framer Logo",
+ "sign-in-framer-partners": "Sign in to Framer Partners",
+ "not-a-framer-partner-apply-today_component0": "Apply today",
+ "not-a-framer-partner-apply-today": "Not a Framer Partner? {component0}"
+ },
+ "app.dub.co/(dashboard)/account/settings/referrals": {
+ "refer-a-friend": "Refer a friend",
+ "activate-referral-link": "Activate your referral link to share the word about Dub and earn cash rewards"
+ },
+ "app.dub.co/(auth)/oauth/authorize": {
+ "select-workspace-api-access": "Select a workspace to grant API access to",
+ "create-new-workspace": "Create new workspace",
+ "decline-action": "Decline",
+ "authorize-action": "Authorize"
+ },
+ "app.dub.co/(dashboard)/account/settings": {
+ "your-name-label": "Your Name",
+ "display-name-description": "This will be your display name on {APP_NAME}.",
+ "your-email-label": "Your Email",
+ "login-email-description": "This will be the email you use to log in to {APP_NAME} and receive notifications."
+ },
+ "partners.dub.co/(apply)/[programSlug]/apply": {
+ "name-label": "Name",
+ "company-name": "Acme, Inc.",
+ "email-label": "Email",
+ "email-address": "panic@thedis.co",
+ "website-social-media_component0": "(optional)",
+ "website-social-media": "Website / Social media channel {component0}",
+ "website-url": "https://example.com",
+ "promotion-plan": "How do you plan to promote",
+ "additional-questions_component0": "(optional)",
+ "additional-questions": "Any additional questions or comments? {component0}",
+ "submit-application": "Submit application"
+ },
+ "app.dub.co/(onboarding)/onboarding/(steps)": {
+ "paid-plan-required": " Paid plan required",
+ "skip-onboarding": " Skip onboarding"
+ },
+ "app.dub.co/(dashboard)/account/settings/security": {
+ "password-label": "Password",
+ "password-description": " You can set a password to use with your Dub account.",
+ "account-provider-info": "Your account is managed by {component0}.",
+ "create-account-password": "Create account password",
+ "manage-account-password-description": "Manage your account password on {processEnvNextPublicAppName}.",
+ "current-password-label": "Current Password",
+ "new-password-label": "New Password",
+ "password-requirements-header": "Password requirements",
+ "update-password-button": "Update Password",
+ "password": "Password"
+ },
+ "app.dub.co/(auth)/auth/reset-password/[token]": {
+ "invalid-reset-token": "Invalid Reset Token",
+ "invalid-or-expired-reset-token-message": "The password reset token is invalid or expired. Please request a new one.",
+ "reset-password": "Reset your password",
+ "enter-new-password": "Enter new password for your account."
+ },
+ "app.dub.co/(dashboard)/[slug]/settings/library/utm": {
+ "edit-action": "Edit",
+ "delete-action": "Delete"
+ },
+ "app.dub.co/(onboarding)/onboarding": {
+ "next-button": "Next"
+ },
+ "app.dub.co/(onboarding)/onboarding/(steps)/workspace": {
+ "what-is-a-workspace": "What is a workspace?"
+ },
+ "app.dub.co/(dashboard)/[slug]/settings/oauth-apps/new": {
+ "back-to-oauth-apps": "Back to OAuth Apps"
+ },
+ "app.dub.co/(dashboard)/[slug]/settings/integrations/[integrationSlug]/manage": {
+ "back-to-integrations": "Back to integrations"
+ },
+ "partners.dub.co/(apply)/[programSlug]/apply/success": {
+ "enrolled": "Enrolled",
+ "overview": "Overview",
+ "payouts": "Payouts",
+ "events": "Events",
+ "links": "Links",
+ "resources": "Resources",
+ "overview-duplicate": "Overview",
+ "refer-and-earn": "Refer and Earn",
+ "earn": "Earn",
+ "conversion-reward": "for each conversion, and again",
+ "monthly-earnings": "every month",
+ "customer-lifetime-earnings": "for the customer's lifetime.",
+ "referral-link": "Referral link",
+ "referral-link-example": "refer.dub.co/steven",
+ "invite-via-email": "Invite via email",
+ "earnings": "Earnings",
+ "last-24-hours": "Last 24 hours",
+ "oct-1": "Oct 1",
+ "oct-5": "Oct 5",
+ "oct-10": "Oct 10",
+ "oct-15": "Oct 15",
+ "oct-20": "Oct 20",
+ "oct-25": "Oct 25",
+ "oct-31": "Oct 31"
+ },
+ "app.dub.co/(dashboard)/[slug]/settings/domains": {
+ "default-domains-title": "Default Domains",
+ "default-branded-domains-info_component0": "Learn more.",
+ "default-branded-domains-info": "Leverage default branded domains from Dub for specific links. {component0}",
+ "pro-plan-restriction-message": "You can only use dub.link on a Pro plan and above. Upgrade to Pro to use this domain.",
+ "pro-feature-discovery-message": "You've discovered a Pro feature!"
+ },
+ "app.dub.co/(dashboard)/[slug]/programs/[programId]/partners": {
+ "all-items": "All",
+ "top-partners": "Top partners",
+ "approved-status": "Approved",
+ "pending-status": "Pending"
+ },
+ "api/og/analytics": {
+ "favicon-icon": "favicon",
+ "last-24-hours": "Last 24 hours",
+ "total-clicks": "Total Clicks"
+ },
+ "app.dub.co/(dashboard)/[slug]/settings/security": {
+ "provider-logo": "{provider} logo",
+ "saml-single-sign-on": "SAML Single Sign-On",
+ "saml-sso-setup-description": "Set up SAML Single Sign-On (SSO) to allow your team to sign in to {processEnvNextPublicAppName} with your identity provider.",
+ "remove-button": "Remove",
+ "edit-button": "Edit",
+ "configure-button": "Configure",
+ "saml-sso-enterprise-warning": "SAML SSO is only available on Enterprise plans. Upgrade to get started.",
+ "saml-sso-learn-more": "Learn more about SAML SSO.",
+ "provider-logo-template": "{provider} logo",
+ "directory-sync": "Directory Sync",
+ "directory-sync-description": "Automatically provision and deprovision users from your identity provider.",
+ "view-configuration-button": "View configuration",
+ "remove-button-duplicate": "Remove",
+ "edit-button-duplicate": "Edit",
+ "configure-button-duplicate": "Configure",
+ "scim-directory-sync-enterprise-warning": "SCIM Directory Sync is only available on Enterprise plans. Upgrade to get started.",
+ "scim-directory-sync-learn-more": "Learn more about SCIM Directory Sync."
+ },
+ "app.dub.co/(dashboard)/[slug]/settings/billing/invoices": {
+ "invoices-title": "Invoices",
+ "invoices-history-description": "A history of all your Dub invoices",
+ "no-invoices-found-message": "No invoices found",
+ "no-invoices-yet-message": "You don't have any invoices yet",
+ "total-label": "Total",
+ "view-invoice-button": "View invoice",
+ "view-invoice-label": "View invoice"
+ },
+ "../ui/auth/register": {
+ "continue-with-google": "Continue with Google",
+ "continue-with-github": "Continue with GitHub"
+ }
+}
diff --git a/apps/web/app/partners.dub.co/(apply)/[programSlug]/apply/form.tsx b/apps/web/app/partners.dub.co/(apply)/[programSlug]/apply/form.tsx
index 225b633288..9c7602e93f 100644
--- a/apps/web/app/partners.dub.co/(apply)/[programSlug]/apply/form.tsx
+++ b/apps/web/app/partners.dub.co/(apply)/[programSlug]/apply/form.tsx
@@ -1,4 +1,5 @@
"use client";
+import { useTranslations } from "next-intl";
import { createProgramApplicationAction } from "@/lib/actions/partners/create-program-application";
import { Program } from "@dub/prisma/client";
@@ -25,6 +26,8 @@ export function ProgramApplicationForm({
}: {
program: Pick
;
}) {
+ const t = useTranslations("partners.dub.co/(apply)/[programSlug]/apply");
+
const { isMobile } = useMediaQuery();
const router = useRouter();
const { data: session } = useSession();
@@ -91,7 +94,9 @@ export function ProgramApplicationForm({
className="flex flex-col gap-6"
>
- Name
+
+ {t("name-label")}
+
- Email
+
+ {t("email-label")}
+
- Website / Social media channel
- (optional)
+ {t("website-social-media", {
+ component0: (
+
+ {t("website-social-media_component0")}
+
+ ),
+ })}
- How do you plan to promote {program.name}?
+ {t("promotion-plan")}
+ {program.name}?
- Any additional questions or comments?
- (optional)
+ {t("additional-questions", {
+ component0: (
+
+ {t("additional-questions_component0")}
+
+ ),
+ })}
diff --git a/apps/web/app/partners.dub.co/(apply)/[programSlug]/apply/success/screenshot.tsx b/apps/web/app/partners.dub.co/(apply)/[programSlug]/apply/success/screenshot.tsx
index 1f1e2ce4ab..dca082366d 100644
--- a/apps/web/app/partners.dub.co/(apply)/[programSlug]/apply/success/screenshot.tsx
+++ b/apps/web/app/partners.dub.co/(apply)/[programSlug]/apply/success/screenshot.tsx
@@ -1,11 +1,16 @@
import { ProgramProps } from "@/lib/types";
import { cn, DICEBEAR_AVATAR_URL, truncate } from "@dub/utils";
+import { useTranslations } from "next-intl";
import { SVGProps, useId } from "react";
export function Screenshot({
program,
...rest
}: { program: Pick } & SVGProps) {
+ const t = useTranslations(
+ "partners.dub.co/(apply)/[programSlug]/apply/success",
+ );
+
const id = useId();
return (
@@ -92,7 +97,7 @@ export function Screenshot({
style={{ whiteSpace: "pre" }}
>
- Enrolled
+ {t("enrolled")}
@@ -131,7 +136,7 @@ export function Screenshot({
style={{ whiteSpace: "pre" }}
>
- Overview
+ {t("overview")}
@@ -169,7 +174,7 @@ export function Screenshot({
style={{ whiteSpace: "pre" }}
>
- Payouts
+ {t("payouts")}
- Events
+ {t("events")}
- Links
+ {t("links")}
- Resources
+ {t("resources")}
- Overview
+ {t("overview-duplicate")}
@@ -316,7 +321,7 @@ export function Screenshot({
style={{ whiteSpace: "pre" }}
>
- Refer and Earn
+ {t("refer-and-earn")}
- Earn
+ {t("earn")}
20%
- for each conversion, and again
- every month
+ {t("conversion-reward")}
+ {t("monthly-earnings")}
- for the customer's lifetime.
+ {t("customer-lifetime-earnings")}
- Referral link
+ {t("referral-link")}
- refer.dub.co/steven
+ {t("referral-link-example")}
- Invite via email
+ {t("invite-via-email")}
@@ -691,7 +696,7 @@ export function Screenshot({
style={{ whiteSpace: "pre" }}
>
- Earnings
+ {t("earnings")}
- Last 24 hours
+ {t("last-24-hours")}
- Oct 1
+ {t("oct-1")}
- Oct 5
+ {t("oct-5")}
- Oct 10
+ {t("oct-10")}
- Oct 15
+ {t("oct-15")}
- Oct 20
+ {t("oct-20")}
- Oct 25
+ {t("oct-25")}
- Oct 31
+ {t("oct-31")}
diff --git a/apps/web/app/partners.dub.co/(auth)/(default)/layout.tsx b/apps/web/app/partners.dub.co/(auth)/(default)/layout.tsx
index 04ae4865af..312e48657c 100644
--- a/apps/web/app/partners.dub.co/(auth)/(default)/layout.tsx
+++ b/apps/web/app/partners.dub.co/(auth)/(default)/layout.tsx
@@ -1,10 +1,13 @@
import { Grid, Wordmark } from "@dub/ui";
+import { useTranslations } from "next-intl";
export default function PartnerAuthLayout({
children,
}: {
children: React.ReactNode;
}) {
+ const t = useTranslations("partners.dub.co/(auth)/(default)");
+
return (