diff --git a/.env.example b/.env.example index 06498f2bc..9250ab9cf 100644 --- a/.env.example +++ b/.env.example @@ -5,9 +5,9 @@ NEXTAUTH_SECRET="secret" # [[CRYPTO]] # Application Key for symmetric encryption and decryption # REQUIRED: This should be a random string of at least 32 characters -NEXT_PRIVATE_ENCRYPTION_KEY="" +NEXT_PRIVATE_ENCRYPTION_KEY="CAFEBABE" # REQUIRED: This should be a random string of at least 32 characters -NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="" +NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="DEADBEEF" # [[AUTH OPTIONAL]] NEXT_PRIVATE_GOOGLE_CLIENT_ID="" diff --git a/apps/marketing/src/app/(marketing)/[content]/page.tsx b/apps/marketing/src/app/(marketing)/[content]/page.tsx index 5c846e9f2..62c83f400 100644 --- a/apps/marketing/src/app/(marketing)/[content]/page.tsx +++ b/apps/marketing/src/app/(marketing)/[content]/page.tsx @@ -15,7 +15,7 @@ export const generateMetadata = ({ params }: { params: { content: string } }) => notFound(); } - return { title: `Documenso - ${document.title}` }; + return { title: document.title }; }; const mdxComponents: MDXComponents = { diff --git a/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx b/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx index f1952cc72..866539a92 100644 --- a/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx +++ b/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx @@ -18,7 +18,9 @@ export const generateMetadata = ({ params }: { params: { post: string } }) => { } return { - title: `Documenso - ${blogPost.title}`, + title: { + absolute: `${blogPost.title} - Documenso Blog`, + }, description: blogPost.description, }; }; diff --git a/apps/marketing/src/app/(marketing)/blog/page.tsx b/apps/marketing/src/app/(marketing)/blog/page.tsx index 747a56ddf..2eac963d1 100644 --- a/apps/marketing/src/app/(marketing)/blog/page.tsx +++ b/apps/marketing/src/app/(marketing)/blog/page.tsx @@ -1,5 +1,10 @@ +import type { Metadata } from 'next'; + import { allBlogPosts } from 'contentlayer/generated'; +export const metadata: Metadata = { + title: 'Blog', +}; export default function BlogPage() { const blogPosts = allBlogPosts.sort((a, b) => { const dateA = new Date(a.date); diff --git a/apps/marketing/src/app/(marketing)/open/page.tsx b/apps/marketing/src/app/(marketing)/open/page.tsx index e237919bc..a1fea41e4 100644 --- a/apps/marketing/src/app/(marketing)/open/page.tsx +++ b/apps/marketing/src/app/(marketing)/open/page.tsx @@ -1,3 +1,5 @@ +import type { Metadata } from 'next'; + import { z } from 'zod'; import { getUserMonthlyGrowth } from '@documenso/lib/server-only/user/get-user-monthly-growth'; @@ -14,6 +16,10 @@ import { MonthlyTotalUsersChart } from './monthly-total-users-chart'; import { TeamMembers } from './team-members'; import { OpenPageTooltip } from './tooltip'; +export const metadata: Metadata = { + title: 'Open Startup', +}; + export const revalidate = 3600; export const dynamic = 'force-dynamic'; diff --git a/apps/marketing/src/app/(marketing)/oss-friends/page.tsx b/apps/marketing/src/app/(marketing)/oss-friends/page.tsx index a91446408..65a4a55f8 100644 --- a/apps/marketing/src/app/(marketing)/oss-friends/page.tsx +++ b/apps/marketing/src/app/(marketing)/oss-friends/page.tsx @@ -1,3 +1,4 @@ +import type { Metadata } from 'next'; import Image from 'next/image'; import { z } from 'zod'; @@ -5,7 +6,12 @@ import { z } from 'zod'; import backgroundPattern from '@documenso/assets/images/background-pattern.png'; import { OSSFriendsContainer } from './container'; -import { TOSSFriendsSchema, ZOSSFriendsSchema } from './schema'; +import type { TOSSFriendsSchema } from './schema'; +import { ZOSSFriendsSchema } from './schema'; + +export const metadata: Metadata = { + title: 'OSS Friends', +}; export default async function OSSFriendsPage() { const ossFriends: TOSSFriendsSchema = await fetch('https://formbricks.com/api/oss-friends', { diff --git a/apps/marketing/src/app/(marketing)/page.tsx b/apps/marketing/src/app/(marketing)/page.tsx index 377384701..10918299a 100644 --- a/apps/marketing/src/app/(marketing)/page.tsx +++ b/apps/marketing/src/app/(marketing)/page.tsx @@ -1,4 +1,5 @@ /* eslint-disable no-unused-vars, @typescript-eslint/no-unused-vars */ +import type { Metadata } from 'next'; import { Caveat } from 'next/font/google'; import { cn } from '@documenso/ui/lib/utils'; @@ -10,6 +11,11 @@ import { OpenBuildTemplateBento } from '~/components/(marketing)/open-build-temp import { ShareConnectPaidWidgetBento } from '~/components/(marketing)/share-connect-paid-widget-bento'; export const revalidate = 600; +export const metadata: Metadata = { + title: { + absolute: 'Documenso - The Open Source DocuSign Alternative', + }, +}; const fontCaveat = Caveat({ weight: ['500'], diff --git a/apps/marketing/src/app/(marketing)/pricing/page.tsx b/apps/marketing/src/app/(marketing)/pricing/page.tsx index 92043b3b3..e4c7b776a 100644 --- a/apps/marketing/src/app/(marketing)/pricing/page.tsx +++ b/apps/marketing/src/app/(marketing)/pricing/page.tsx @@ -1,5 +1,4 @@ -'use client'; - +import type { Metadata } from 'next'; import Link from 'next/link'; import { @@ -12,6 +11,10 @@ import { Button } from '@documenso/ui/primitives/button'; import { PricingTable } from '~/components/(marketing)/pricing-table'; +export const metadata: Metadata = { + title: 'Pricing', +}; + export type PricingPageProps = { searchParams?: { planId?: string; diff --git a/apps/marketing/src/app/(marketing)/singleplayer/page.tsx b/apps/marketing/src/app/(marketing)/singleplayer/page.tsx index a98906476..aafad32a8 100644 --- a/apps/marketing/src/app/(marketing)/singleplayer/page.tsx +++ b/apps/marketing/src/app/(marketing)/singleplayer/page.tsx @@ -1,5 +1,11 @@ +import type { Metadata } from 'next'; + import { SinglePlayerClient } from './client'; +export const metadata: Metadata = { + title: 'Singleplayer', +}; + export const revalidate = 0; // !: This entire file is a hack to get around failed prerendering of diff --git a/apps/marketing/src/app/layout.tsx b/apps/marketing/src/app/layout.tsx index 05206a76f..1745149c6 100644 --- a/apps/marketing/src/app/layout.tsx +++ b/apps/marketing/src/app/layout.tsx @@ -18,7 +18,10 @@ const fontInter = Inter({ subsets: ['latin'], variable: '--font-sans' }); const fontCaveat = Caveat({ subsets: ['latin'], variable: '--font-signature' }); export const metadata = { - title: 'Documenso - The Open Source DocuSign Alternative', + title: { + template: '%s - Documenso', + default: 'Documenso', + }, description: 'Join Documenso, the open signing infrastructure, and get a 10x better signing experience. Pricing starts at $30/mo. forever! Sign in now and enjoy a faster, smarter, and more beautiful document signing process. Integrates with your favorite tools, customizable, and expandable. Support our mission and become a part of our open-source community.', keywords: diff --git a/apps/web/src/app/(dashboard)/documents/page.tsx b/apps/web/src/app/(dashboard)/documents/page.tsx index 8bb321377..a15d65306 100644 --- a/apps/web/src/app/(dashboard)/documents/page.tsx +++ b/apps/web/src/app/(dashboard)/documents/page.tsx @@ -1,3 +1,4 @@ +import type { Metadata } from 'next'; import Link from 'next/link'; import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session'; @@ -25,6 +26,9 @@ export type DocumentsPageProps = { }; }; +export const metadata: Metadata = { + title: 'Documents', +}; export default async function DocumentsPage({ searchParams = {} }: DocumentsPageProps) { const { user } = await getRequiredServerComponentSession(); diff --git a/apps/web/src/app/(dashboard)/settings/billing/page.tsx b/apps/web/src/app/(dashboard)/settings/billing/page.tsx index 74e4bd685..e226a7e39 100644 --- a/apps/web/src/app/(dashboard)/settings/billing/page.tsx +++ b/apps/web/src/app/(dashboard)/settings/billing/page.tsx @@ -1,3 +1,4 @@ +import type { Metadata } from 'next'; import { redirect } from 'next/navigation'; import { match } from 'ts-pattern'; @@ -17,6 +18,10 @@ import { LocaleDate } from '~/components/formatter/locale-date'; import { BillingPlans } from './billing-plans'; import { BillingPortalButton } from './billing-portal-button'; +export const metadata: Metadata = { + title: 'Billing', +}; + export default async function BillingSettingsPage() { let { user } = await getRequiredServerComponentSession(); diff --git a/apps/web/src/app/(dashboard)/settings/profile/page.tsx b/apps/web/src/app/(dashboard)/settings/profile/page.tsx index cb64fb9cd..60f7da49c 100644 --- a/apps/web/src/app/(dashboard)/settings/profile/page.tsx +++ b/apps/web/src/app/(dashboard)/settings/profile/page.tsx @@ -1,7 +1,13 @@ +import type { Metadata } from 'next'; + import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session'; import { ProfileForm } from '~/components/forms/profile'; +export const metadata: Metadata = { + title: 'Profile', +}; + export default async function ProfileSettingsPage() { const { user } = await getRequiredServerComponentSession(); diff --git a/apps/web/src/app/(dashboard)/settings/security/page.tsx b/apps/web/src/app/(dashboard)/settings/security/page.tsx index ae97e7fb5..854ba66ce 100644 --- a/apps/web/src/app/(dashboard)/settings/security/page.tsx +++ b/apps/web/src/app/(dashboard)/settings/security/page.tsx @@ -1,3 +1,5 @@ +import type { Metadata } from 'next'; + import { IDENTITY_PROVIDER_NAME } from '@documenso/lib/constants/auth'; import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session'; @@ -5,6 +7,10 @@ import { AuthenticatorApp } from '~/components/forms/2fa/authenticator-app'; import { RecoveryCodes } from '~/components/forms/2fa/recovery-codes'; import { PasswordForm } from '~/components/forms/password'; +export const metadata: Metadata = { + title: 'Security', +}; + export default async function SecuritySettingsPage() { const { user } = await getRequiredServerComponentSession(); diff --git a/apps/web/src/app/(dashboard)/templates/page.tsx b/apps/web/src/app/(dashboard)/templates/page.tsx index f4167e42a..d3dacd501 100644 --- a/apps/web/src/app/(dashboard)/templates/page.tsx +++ b/apps/web/src/app/(dashboard)/templates/page.tsx @@ -1,5 +1,7 @@ import React from 'react'; +import type { Metadata } from 'next'; + import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session'; import { getTemplates } from '@documenso/lib/server-only/template/get-templates'; @@ -14,6 +16,10 @@ type TemplatesPageProps = { }; }; +export const metadata: Metadata = { + title: 'Templates', +}; + export default async function TemplatesPage({ searchParams = {} }: TemplatesPageProps) { const { user } = await getRequiredServerComponentSession(); const page = Number(searchParams.page) || 1; diff --git a/apps/web/src/app/(signing)/sign/[token]/complete/document-preview-button.tsx b/apps/web/src/app/(signing)/sign/[token]/complete/document-preview-button.tsx index 1ac50f1c0..c0881bd44 100644 --- a/apps/web/src/app/(signing)/sign/[token]/complete/document-preview-button.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/complete/document-preview-button.tsx @@ -30,7 +30,7 @@ export const DocumentPreviewButton = ({ {...props} > - View Document + View Original Document diff --git a/apps/web/src/app/(signing)/sign/[token]/complete/page.tsx b/apps/web/src/app/(signing)/sign/[token]/complete/page.tsx index ab73755ab..3d5814113 100644 --- a/apps/web/src/app/(signing)/sign/[token]/complete/page.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/complete/page.tsx @@ -128,7 +128,7 @@ export default async function CompletedSigningPage({ /> ) : ( diff --git a/apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx b/apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx index e4d4571fc..1e86e99bc 100644 --- a/apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx @@ -45,7 +45,7 @@ export const SignDialog = ({
-
Sign Document
+
Sign Document
You are about to finish signing "{truncatedTitle}". Are you sure?
diff --git a/apps/web/src/app/(unauthenticated)/check-email/page.tsx b/apps/web/src/app/(unauthenticated)/check-email/page.tsx index fffbc44c1..94b410a8e 100644 --- a/apps/web/src/app/(unauthenticated)/check-email/page.tsx +++ b/apps/web/src/app/(unauthenticated)/check-email/page.tsx @@ -1,7 +1,12 @@ +import type { Metadata } from 'next'; import Link from 'next/link'; import { Button } from '@documenso/ui/primitives/button'; +export const metadata: Metadata = { + title: 'Forgot password', +}; + export default function ForgotPasswordPage() { return (
diff --git a/apps/web/src/app/(unauthenticated)/forgot-password/page.tsx b/apps/web/src/app/(unauthenticated)/forgot-password/page.tsx index 20ecddf4d..36c023027 100644 --- a/apps/web/src/app/(unauthenticated)/forgot-password/page.tsx +++ b/apps/web/src/app/(unauthenticated)/forgot-password/page.tsx @@ -1,7 +1,12 @@ +import type { Metadata } from 'next'; import Link from 'next/link'; import { ForgotPasswordForm } from '~/components/forms/forgot-password'; +export const metadata: Metadata = { + title: 'Forgot Password', +}; + export default function ForgotPasswordPage() { return (
diff --git a/apps/web/src/app/(unauthenticated)/reset-password/page.tsx b/apps/web/src/app/(unauthenticated)/reset-password/page.tsx index c4f521363..93cd41ebb 100644 --- a/apps/web/src/app/(unauthenticated)/reset-password/page.tsx +++ b/apps/web/src/app/(unauthenticated)/reset-password/page.tsx @@ -1,7 +1,12 @@ +import type { Metadata } from 'next'; import Link from 'next/link'; import { Button } from '@documenso/ui/primitives/button'; +export const metadata: Metadata = { + title: 'Reset Password', +}; + export default function ResetPasswordPage() { return (
diff --git a/apps/web/src/app/(unauthenticated)/signin/page.tsx b/apps/web/src/app/(unauthenticated)/signin/page.tsx index bbea70ecb..11f47d734 100644 --- a/apps/web/src/app/(unauthenticated)/signin/page.tsx +++ b/apps/web/src/app/(unauthenticated)/signin/page.tsx @@ -1,3 +1,4 @@ +import type { Metadata } from 'next'; import Link from 'next/link'; import { env } from 'next-runtime-env'; @@ -6,6 +7,10 @@ import { IS_GOOGLE_SSO_ENABLED } from '@documenso/lib/constants/auth'; import { SignInForm } from '~/components/forms/signin'; +export const metadata: Metadata = { + title: 'Sign In', +}; + export default function SignInPage() { const NEXT_PUBLIC_DISABLE_SIGNUP = env('NEXT_PUBLIC_DISABLE_SIGNUP'); diff --git a/apps/web/src/app/(unauthenticated)/signup/page.tsx b/apps/web/src/app/(unauthenticated)/signup/page.tsx index e6e8b0176..2387b1c96 100644 --- a/apps/web/src/app/(unauthenticated)/signup/page.tsx +++ b/apps/web/src/app/(unauthenticated)/signup/page.tsx @@ -1,3 +1,4 @@ +import type { Metadata } from 'next'; import Link from 'next/link'; import { redirect } from 'next/navigation'; @@ -7,6 +8,10 @@ import { IS_GOOGLE_SSO_ENABLED } from '@documenso/lib/constants/auth'; import { SignUpForm } from '~/components/forms/signup'; +export const metadata: Metadata = { + title: 'Sign Up', +}; + export default function SignUpPage() { const NEXT_PUBLIC_DISABLE_SIGNUP = env('NEXT_PUBLIC_DISABLE_SIGNUP'); diff --git a/apps/web/src/app/(unauthenticated)/verify-email/page.tsx b/apps/web/src/app/(unauthenticated)/verify-email/page.tsx index 04202d19b..30d2baf16 100644 --- a/apps/web/src/app/(unauthenticated)/verify-email/page.tsx +++ b/apps/web/src/app/(unauthenticated)/verify-email/page.tsx @@ -1,9 +1,14 @@ +import type { Metadata } from 'next'; import Link from 'next/link'; import { XCircle } from 'lucide-react'; import { Button } from '@documenso/ui/primitives/button'; +export const metadata: Metadata = { + title: 'Verify Email', +}; + export default function EmailVerificationWithoutTokenPage() { return (
diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index f36d59353..1e6619a46 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -24,7 +24,10 @@ const fontCaveat = Caveat({ subsets: ['latin'], variable: '--font-signature' }); const NEXT_PUBLIC_WEBAPP_URL = env('NEXT_PUBLIC_WEBAPP_URL'); export const metadata = { - title: 'Documenso - The Open Source DocuSign Alternative', + title: { + template: '%s - Documenso', + default: 'Documenso', + }, description: 'Join Documenso, the open signing infrastructure, and get a 10x better signing experience. Pricing starts at $30/mo. forever! Sign in now and enjoy a faster, smarter, and more beautiful document signing process. Integrates with your favorite tools, customizable, and expandable. Support our mission and become a part of our open-source community.', keywords: diff --git a/apps/web/src/components/(dashboard)/layout/header.tsx b/apps/web/src/components/(dashboard)/layout/header.tsx index bdae6c511..ba35671e6 100644 --- a/apps/web/src/components/(dashboard)/layout/header.tsx +++ b/apps/web/src/components/(dashboard)/layout/header.tsx @@ -33,7 +33,7 @@ export const Header = ({ className, user, ...props }: HeaderProps) => { return (
5 && 'border-b-border', className, )} diff --git a/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx b/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx index 252432b89..f2432c071 100644 --- a/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx +++ b/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx @@ -68,7 +68,7 @@ export const ProfileDropdown = ({ user }: ProfileDropdownProps) => { - + Account {isUserAdmin && ( @@ -122,7 +122,7 @@ export const ProfileDropdown = ({ user }: ProfileDropdownProps) => { Themes - + Light