mirror of
https://github.com/documenso/documenso.git
synced 2025-11-12 15:53:02 +10:00
feat: add next-runtime-env (#869)
This PR adds the package [next-runtime-env](https://github.com/expatfile/next-runtime-env/) to populate the public environment variables at runtime.
This commit is contained in:
@ -5,7 +5,7 @@ authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-01-25
|
||||
Tags:
|
||||
tags:
|
||||
- Vision
|
||||
- Mission
|
||||
- Open Source
|
||||
|
||||
@ -5,7 +5,7 @@ authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-01-10
|
||||
Tags:
|
||||
tags:
|
||||
- GitHub
|
||||
- Backlog
|
||||
- Roadmap
|
||||
|
||||
@ -5,7 +5,7 @@ authorName: 'Timur Ercan'
|
||||
authorImage: '/blog/blog-author-timur.jpeg'
|
||||
authorRole: 'Co-Founder'
|
||||
date: 2024-02-06
|
||||
Tags:
|
||||
tags:
|
||||
- Founders
|
||||
- Mission
|
||||
- Open Source
|
||||
|
||||
@ -12,7 +12,7 @@ export const generateMetadata = ({ params }: { params: { content: string } }) =>
|
||||
const document = allDocuments.find((post) => post._raw.flattenedPath === params.content);
|
||||
|
||||
if (!document) {
|
||||
notFound();
|
||||
return { title: 'Not Found' };
|
||||
}
|
||||
|
||||
return { title: document.title };
|
||||
|
||||
@ -7,6 +7,8 @@ import { ChevronLeft } from 'lucide-react';
|
||||
import type { MDXComponents } from 'mdx/types';
|
||||
import { useMDXComponent } from 'next-contentlayer/hooks';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export const generateStaticParams = () =>
|
||||
allBlogPosts.map((post) => ({ post: post._raw.flattenedPath }));
|
||||
|
||||
@ -14,7 +16,9 @@ export const generateMetadata = ({ params }: { params: { post: string } }) => {
|
||||
const blogPost = allBlogPosts.find((post) => post._raw.flattenedPath === `blog/${params.post}`);
|
||||
|
||||
if (!blogPost) {
|
||||
notFound();
|
||||
return {
|
||||
title: 'Not Found',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@ -4,6 +4,7 @@ import { redirect } from 'next/navigation';
|
||||
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { redis } from '@documenso/lib/server-only/redis';
|
||||
import { stripe } from '@documenso/lib/server-only/stripe';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
@ -12,6 +13,8 @@ import { Button } from '@documenso/ui/primitives/button';
|
||||
|
||||
import { PasswordReveal } from '~/components/(marketing)/password-reveal';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
const fontCaveat = Caveat({
|
||||
weight: ['500'],
|
||||
subsets: ['latin'],
|
||||
@ -175,11 +178,7 @@ export default async function ClaimedPlanPage({ searchParams = {} }: ClaimedPlan
|
||||
This is a temporary password. Please change it as soon as possible.
|
||||
</p>
|
||||
|
||||
<Link
|
||||
href={`${process.env.NEXT_PUBLIC_WEBAPP_URL}/signin`}
|
||||
target="_blank"
|
||||
className="mt-4 block"
|
||||
>
|
||||
<Link href={`${NEXT_PUBLIC_WEBAPP_URL()}/signin`} target="_blank" className="mt-4 block">
|
||||
<Button size="lg" className="text-base">
|
||||
Let's get started!
|
||||
<ArrowRight className="ml-2 h-5 w-5" />
|
||||
|
||||
@ -15,6 +15,8 @@ export const metadata: Metadata = {
|
||||
title: 'Pricing',
|
||||
};
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export type PricingPageProps = {
|
||||
searchParams?: {
|
||||
planId?: string;
|
||||
|
||||
@ -6,6 +6,7 @@ import Link from 'next/link';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
import { useAnalytics } from '@documenso/lib/client-only/hooks/use-analytics';
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { base64 } from '@documenso/lib/universal/base64';
|
||||
import { putFile } from '@documenso/lib/universal/upload/put-file';
|
||||
import type { Field, Recipient } from '@documenso/prisma/client';
|
||||
@ -190,7 +191,7 @@ export const SinglePlayerClient = () => {
|
||||
<p className="text-foreground mx-auto mt-4 max-w-[50ch] text-lg leading-normal">
|
||||
Create a{' '}
|
||||
<Link
|
||||
href={`${process.env.NEXT_PUBLIC_WEBAPP_URL}/signup`}
|
||||
href={`${NEXT_PUBLIC_WEBAPP_URL()}/signup`}
|
||||
target="_blank"
|
||||
className="hover:text-foreground/80 font-semibold transition-colors"
|
||||
>
|
||||
|
||||
@ -7,6 +7,7 @@ export const metadata: Metadata = {
|
||||
};
|
||||
|
||||
export const revalidate = 0;
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
// !: This entire file is a hack to get around failed prerendering of
|
||||
// !: the Single Player Mode page. This regression was introduced during
|
||||
|
||||
@ -3,6 +3,7 @@ import { Suspense } from 'react';
|
||||
import { Caveat, Inter } from 'next/font/google';
|
||||
|
||||
import { FeatureFlagProvider } from '@documenso/lib/client-only/providers/feature-flag';
|
||||
import { NEXT_PUBLIC_MARKETING_URL } from '@documenso/lib/constants/app';
|
||||
import { getAllAnonymousFlags } from '@documenso/lib/universal/get-feature-flag';
|
||||
import { TrpcProvider } from '@documenso/trpc/react';
|
||||
import { cn } from '@documenso/ui/lib/utils';
|
||||
@ -17,32 +18,35 @@ import './globals.css';
|
||||
const fontInter = Inter({ subsets: ['latin'], variable: '--font-sans' });
|
||||
const fontCaveat = Caveat({ subsets: ['latin'], variable: '--font-signature' });
|
||||
|
||||
export const metadata = {
|
||||
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:
|
||||
'Documenso, open source, DocuSign alternative, document signing, open signing infrastructure, open-source community, fast signing, beautiful signing, smart templates',
|
||||
authors: { name: 'Documenso, Inc.' },
|
||||
robots: 'index, follow',
|
||||
openGraph: {
|
||||
title: 'Documenso - The Open Source DocuSign Alternative',
|
||||
export function generateMetadata() {
|
||||
return {
|
||||
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.',
|
||||
type: 'website',
|
||||
images: [`${process.env.NEXT_PUBLIC_MARKETING_URL}/opengraph-image.jpg`],
|
||||
},
|
||||
twitter: {
|
||||
site: '@documenso',
|
||||
card: 'summary_large_image',
|
||||
images: [`${process.env.NEXT_PUBLIC_MARKETING_URL}/opengraph-image.jpg`],
|
||||
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:
|
||||
'Documenso, open source, DocuSign alternative, document signing, open signing infrastructure, open-source community, fast signing, beautiful signing, smart templates',
|
||||
authors: { name: 'Documenso, Inc.' },
|
||||
robots: 'index, follow',
|
||||
metadataBase: new URL(NEXT_PUBLIC_MARKETING_URL() ?? 'http://localhost:3000'),
|
||||
openGraph: {
|
||||
title: 'Documenso - The Open Source DocuSign Alternative',
|
||||
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.',
|
||||
type: 'website',
|
||||
images: ['/opengraph-image.jpg'],
|
||||
},
|
||||
twitter: {
|
||||
site: '@documenso',
|
||||
card: 'summary_large_image',
|
||||
images: ['/opengraph-image.jpg'],
|
||||
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.',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
const flags = await getAllAnonymousFlags();
|
||||
|
||||
@ -8,6 +8,7 @@ import Link from 'next/link';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { usePlausible } from 'next-plausible';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { cn } from '@documenso/ui/lib/utils';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
|
||||
@ -82,11 +83,7 @@ export const PricingTable = ({ className, ...props }: PricingTableProps) => {
|
||||
</p>
|
||||
|
||||
<Button className="rounded-full text-base" asChild>
|
||||
<Link
|
||||
href={`${process.env.NEXT_PUBLIC_WEBAPP_URL}/signup`}
|
||||
target="_blank"
|
||||
className="mt-6"
|
||||
>
|
||||
<Link href={`${NEXT_PUBLIC_WEBAPP_URL()}/signup`} target="_blank" className="mt-6">
|
||||
Signup Now
|
||||
</Link>
|
||||
</Button>
|
||||
@ -117,7 +114,7 @@ export const PricingTable = ({ className, ...props }: PricingTableProps) => {
|
||||
</p>
|
||||
|
||||
<Button className="mt-6 rounded-full text-base" asChild>
|
||||
<Link href={`${process.env.NEXT_PUBLIC_WEBAPP_URL}/signup`}>Signup Now</Link>
|
||||
<Link href={`${NEXT_PUBLIC_WEBAPP_URL()}/signup`}>Signup Now</Link>
|
||||
</Button>
|
||||
|
||||
<div className="mt-8 flex w-full flex-col divide-y">
|
||||
|
||||
@ -6,6 +6,7 @@ import Link from 'next/link';
|
||||
|
||||
import signingCelebration from '@documenso/assets/images/signing-celebration.png';
|
||||
import { useFeatureFlags } from '@documenso/lib/client-only/providers/feature-flag';
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import type { Signature } from '@documenso/prisma/client';
|
||||
import { DocumentStatus } from '@documenso/prisma/client';
|
||||
import type { DocumentWithRecipient } from '@documenso/prisma/types/document-with-recipient';
|
||||
@ -85,7 +86,7 @@ export const SinglePlayerModeSuccess = ({
|
||||
<p className="text-muted-foreground/60 mt-16 text-center text-sm">
|
||||
Create a{' '}
|
||||
<Link
|
||||
href={`${process.env.NEXT_PUBLIC_WEBAPP_URL}/signup`}
|
||||
href={`${NEXT_PUBLIC_WEBAPP_URL()}/signup`}
|
||||
target="_blank"
|
||||
className="text-documenso-700 hover:text-documenso-600 whitespace-nowrap"
|
||||
>
|
||||
|
||||
@ -7,6 +7,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { Loader } from 'lucide-react';
|
||||
import { usePlausible } from 'next-plausible';
|
||||
import { env } from 'next-runtime-env';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
|
||||
@ -144,7 +145,11 @@ export const Widget = ({ className, children, ...props }: WidgetProps) => {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
|
||||
const planId = process.env.NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID;
|
||||
const planId = env('NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID');
|
||||
|
||||
if (!planId) {
|
||||
throw new Error('No plan ID found.');
|
||||
}
|
||||
|
||||
const claimPlanInput = signatureDataUrl
|
||||
? {
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
import { randomUUID } from 'crypto';
|
||||
|
||||
import { TEarlyAdopterCheckoutMetadataSchema } from '@documenso/ee/server-only/stripe/webhook/early-adopter-checkout-metadata';
|
||||
import type { TEarlyAdopterCheckoutMetadataSchema } from '@documenso/ee/server-only/stripe/webhook/early-adopter-checkout-metadata';
|
||||
import { NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { redis } from '@documenso/lib/server-only/redis';
|
||||
import { stripe } from '@documenso/lib/server-only/stripe';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { TClaimPlanResponseSchema, ZClaimPlanRequestSchema } from '~/api/claim-plan/types';
|
||||
import type { TClaimPlanResponseSchema } from '~/api/claim-plan/types';
|
||||
import { ZClaimPlanRequestSchema } from '~/api/claim-plan/types';
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
@ -40,7 +42,7 @@ export default async function handler(
|
||||
|
||||
if (user) {
|
||||
return res.status(200).json({
|
||||
redirectUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/signin`,
|
||||
redirectUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/signin`,
|
||||
});
|
||||
}
|
||||
|
||||
@ -77,8 +79,8 @@ export default async function handler(
|
||||
mode: 'subscription',
|
||||
metadata,
|
||||
allow_promotion_codes: true,
|
||||
success_url: `${process.env.NEXT_PUBLIC_MARKETING_URL}/claimed?sessionId={CHECKOUT_SESSION_ID}`,
|
||||
cancel_url: `${process.env.NEXT_PUBLIC_MARKETING_URL}`,
|
||||
success_url: `${NEXT_PUBLIC_MARKETING_URL()}/claimed?sessionId={CHECKOUT_SESSION_ID}`,
|
||||
cancel_url: `${NEXT_PUBLIC_MARKETING_URL()}`,
|
||||
});
|
||||
|
||||
if (!checkout.url) {
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
import { getStripeCustomerByUser } from '@documenso/ee/server-only/stripe/get-customer';
|
||||
import { getPortalSession } from '@documenso/ee/server-only/stripe/get-portal-session';
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||
|
||||
export const createBillingPortal = async () => {
|
||||
@ -11,6 +12,6 @@ export const createBillingPortal = async () => {
|
||||
|
||||
return getPortalSession({
|
||||
customerId: stripeCustomer.id,
|
||||
returnUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/settings/billing`,
|
||||
returnUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/settings/billing`,
|
||||
});
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
import { getCheckoutSession } from '@documenso/ee/server-only/stripe/get-checkout-session';
|
||||
import { getStripeCustomerByUser } from '@documenso/ee/server-only/stripe/get-customer';
|
||||
import { getPortalSession } from '@documenso/ee/server-only/stripe/get-portal-session';
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||
import { getSubscriptionsByUserId } from '@documenso/lib/server-only/subscription/get-subscriptions-by-user-id';
|
||||
|
||||
@ -27,13 +28,13 @@ export const createCheckout = async ({ priceId }: CreateCheckoutOptions) => {
|
||||
if (foundSubscription) {
|
||||
return getPortalSession({
|
||||
customerId: stripeCustomer.id,
|
||||
returnUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/settings/billing`,
|
||||
returnUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/settings/billing`,
|
||||
});
|
||||
}
|
||||
|
||||
return getCheckoutSession({
|
||||
customerId: stripeCustomer.id,
|
||||
priceId,
|
||||
returnUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/settings/billing`,
|
||||
returnUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/settings/billing`,
|
||||
});
|
||||
};
|
||||
|
||||
@ -3,6 +3,8 @@ import { NextResponse } from 'next/server';
|
||||
|
||||
import { P, match } from 'ts-pattern';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
|
||||
import type { ShareHandlerAPIResponse } from '~/pages/api/share';
|
||||
|
||||
export const runtime = 'edge';
|
||||
@ -37,7 +39,7 @@ export async function GET(_request: Request, { params: { slug } }: SharePageOpen
|
||||
),
|
||||
]);
|
||||
|
||||
const baseUrl = process.env.NEXT_PUBLIC_WEBAPP_URL || 'http://localhost:3000';
|
||||
const baseUrl = NEXT_PUBLIC_WEBAPP_URL() || 'http://localhost:3000';
|
||||
|
||||
const recipientOrSender: ShareHandlerAPIResponse = await fetch(
|
||||
new URL(`/api/share?slug=${slug}`, baseUrl),
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Metadata } from 'next';
|
||||
import type { Metadata } from 'next';
|
||||
import { headers } from 'next/headers';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
import { APP_BASE_URL } from '@documenso/lib/constants/app';
|
||||
import { NEXT_PUBLIC_MARKETING_URL } from '@documenso/lib/constants/app';
|
||||
|
||||
type SharePageProps = {
|
||||
params: { slug: string };
|
||||
@ -16,12 +16,12 @@ export function generateMetadata({ params: { slug } }: SharePageProps) {
|
||||
title: 'Documenso - Join the open source signing revolution',
|
||||
description: 'I just signed with Documenso!',
|
||||
type: 'website',
|
||||
images: [`${APP_BASE_URL}/share/${slug}/opengraph`],
|
||||
images: [`/share/${slug}/opengraph`],
|
||||
},
|
||||
twitter: {
|
||||
site: '@documenso',
|
||||
card: 'summary_large_image',
|
||||
images: [`${APP_BASE_URL}/share/${slug}/opengraph`],
|
||||
images: [`/share/${slug}/opengraph`],
|
||||
description: 'I just signed with Documenso!',
|
||||
},
|
||||
} satisfies Metadata;
|
||||
@ -35,5 +35,5 @@ export default function SharePage() {
|
||||
return null;
|
||||
}
|
||||
|
||||
redirect(process.env.NEXT_PUBLIC_MARKETING_URL ?? 'http://localhost:3001');
|
||||
redirect(NEXT_PUBLIC_MARKETING_URL() ?? 'http://localhost:3001');
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@ import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
import { env } from 'next-runtime-env';
|
||||
|
||||
import { IS_GOOGLE_SSO_ENABLED } from '@documenso/lib/constants/auth';
|
||||
import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt';
|
||||
|
||||
@ -18,6 +20,8 @@ type SignInPageProps = {
|
||||
};
|
||||
|
||||
export default function SignInPage({ searchParams }: SignInPageProps) {
|
||||
const NEXT_PUBLIC_DISABLE_SIGNUP = env('NEXT_PUBLIC_DISABLE_SIGNUP');
|
||||
|
||||
const rawEmail = typeof searchParams.email === 'string' ? searchParams.email : undefined;
|
||||
const email = rawEmail ? decryptSecondaryData(rawEmail) : null;
|
||||
|
||||
@ -39,7 +43,7 @@ export default function SignInPage({ searchParams }: SignInPageProps) {
|
||||
isGoogleSSOEnabled={IS_GOOGLE_SSO_ENABLED}
|
||||
/>
|
||||
|
||||
{process.env.NEXT_PUBLIC_DISABLE_SIGNUP !== 'true' && (
|
||||
{NEXT_PUBLIC_DISABLE_SIGNUP !== 'true' && (
|
||||
<p className="text-muted-foreground mt-6 text-center text-sm">
|
||||
Don't have an account?{' '}
|
||||
<Link href="/signup" className="text-primary duration-200 hover:opacity-70">
|
||||
|
||||
@ -2,6 +2,8 @@ import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
import { env } from 'next-runtime-env';
|
||||
|
||||
import { IS_GOOGLE_SSO_ENABLED } from '@documenso/lib/constants/auth';
|
||||
import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt';
|
||||
|
||||
@ -18,7 +20,9 @@ type SignUpPageProps = {
|
||||
};
|
||||
|
||||
export default function SignUpPage({ searchParams }: SignUpPageProps) {
|
||||
if (process.env.NEXT_PUBLIC_DISABLE_SIGNUP === 'true') {
|
||||
const NEXT_PUBLIC_DISABLE_SIGNUP = env('NEXT_PUBLIC_DISABLE_SIGNUP');
|
||||
|
||||
if (NEXT_PUBLIC_DISABLE_SIGNUP === 'true') {
|
||||
redirect('/signin');
|
||||
}
|
||||
|
||||
|
||||
@ -2,8 +2,11 @@ import { Suspense } from 'react';
|
||||
|
||||
import { Caveat, Inter } from 'next/font/google';
|
||||
|
||||
import { PublicEnvScript } from 'next-runtime-env';
|
||||
|
||||
import { FeatureFlagProvider } from '@documenso/lib/client-only/providers/feature-flag';
|
||||
import { LocaleProvider } from '@documenso/lib/client-only/providers/locale';
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { getServerComponentAllFlags } from '@documenso/lib/server-only/feature-flags/get-server-component-feature-flag';
|
||||
import { getLocale } from '@documenso/lib/server-only/headers/get-locale';
|
||||
import { TrpcProvider } from '@documenso/trpc/react';
|
||||
@ -19,32 +22,35 @@ import './globals.css';
|
||||
const fontInter = Inter({ subsets: ['latin'], variable: '--font-sans' });
|
||||
const fontCaveat = Caveat({ subsets: ['latin'], variable: '--font-signature' });
|
||||
|
||||
export const metadata = {
|
||||
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:
|
||||
'Documenso, open source, DocuSign alternative, document signing, open signing infrastructure, open-source community, fast signing, beautiful signing, smart templates',
|
||||
authors: { name: 'Documenso, Inc.' },
|
||||
robots: 'index, follow',
|
||||
openGraph: {
|
||||
title: 'Documenso - The Open Source DocuSign Alternative',
|
||||
export function generateMetadata() {
|
||||
return {
|
||||
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.',
|
||||
type: 'website',
|
||||
images: [`${process.env.NEXT_PUBLIC_WEBAPP_URL}/opengraph-image.jpg`],
|
||||
},
|
||||
twitter: {
|
||||
site: '@documenso',
|
||||
card: 'summary_large_image',
|
||||
images: [`${process.env.NEXT_PUBLIC_WEBAPP_URL}/opengraph-image.jpg`],
|
||||
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:
|
||||
'Documenso, open source, DocuSign alternative, document signing, open signing infrastructure, open-source community, fast signing, beautiful signing, smart templates',
|
||||
authors: { name: 'Documenso, Inc.' },
|
||||
robots: 'index, follow',
|
||||
metadataBase: new URL(NEXT_PUBLIC_WEBAPP_URL() ?? 'http://localhost:3000'),
|
||||
openGraph: {
|
||||
title: 'Documenso - The Open Source DocuSign Alternative',
|
||||
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.',
|
||||
type: 'website',
|
||||
images: ['/opengraph-image.jpg'],
|
||||
},
|
||||
twitter: {
|
||||
site: '@documenso',
|
||||
card: 'summary_large_image',
|
||||
images: ['/opengraph-image.jpg'],
|
||||
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.',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
const flags = await getServerComponentAllFlags();
|
||||
@ -62,6 +68,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<PublicEnvScript />
|
||||
</head>
|
||||
|
||||
<Suspense>
|
||||
|
||||
@ -4,6 +4,7 @@ import React from 'react';
|
||||
|
||||
import { useCopyToClipboard } from '@documenso/lib/client-only/hooks/use-copy-to-clipboard';
|
||||
import { getRecipientType } from '@documenso/lib/client-only/recipient-type';
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
|
||||
import { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter';
|
||||
import type { Recipient } from '@documenso/prisma/client';
|
||||
@ -25,7 +26,7 @@ export function AvatarWithRecipient({ recipient }: AvatarWithRecipientProps) {
|
||||
return;
|
||||
}
|
||||
|
||||
void copy(`${process.env.NEXT_PUBLIC_WEBAPP_URL}/sign/${recipient.token}`).then(() => {
|
||||
void copy(`${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`).then(() => {
|
||||
toast({
|
||||
title: 'Copied to clipboard',
|
||||
description: 'The signing link has been copied to your clipboard.',
|
||||
|
||||
@ -238,7 +238,7 @@ export const TransferTeamDialog = ({
|
||||
<Alert variant="neutral">
|
||||
<AlertDescription>
|
||||
<ul className="list-outside list-disc space-y-2 pl-4">
|
||||
{IS_BILLING_ENABLED && (
|
||||
{IS_BILLING_ENABLED() && (
|
||||
// Temporary removed.
|
||||
// <li>
|
||||
// {form.getValues('clearPaymentMethods')
|
||||
|
||||
@ -48,7 +48,7 @@ export const DesktopNav = ({ className, ...props }: DesktopNavProps) => {
|
||||
</Button>
|
||||
</Link>
|
||||
|
||||
{IS_BILLING_ENABLED && (
|
||||
{IS_BILLING_ENABLED() && (
|
||||
<Link href={billingPath}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
||||
@ -56,7 +56,7 @@ export const MobileNav = ({ className, ...props }: MobileNavProps) => {
|
||||
</Button>
|
||||
</Link>
|
||||
|
||||
{IS_BILLING_ENABLED && (
|
||||
{IS_BILLING_ENABLED() && (
|
||||
<Link href={billingPath}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
|
||||
/**
|
||||
* getAssetBuffer is used to retrieve array buffers for various assets
|
||||
* that are hosted in the `public` folder.
|
||||
@ -8,7 +10,7 @@
|
||||
* @param path The path to the asset, relative to the `public` folder.
|
||||
*/
|
||||
export const getAssetBuffer = async (path: string) => {
|
||||
const baseUrl = process.env.NEXT_PUBLIC_WEBAPP_URL || 'http://localhost:3000';
|
||||
const baseUrl = NEXT_PUBLIC_WEBAPP_URL() || 'http://localhost:3000';
|
||||
|
||||
return fetch(new URL(path, baseUrl)).then(async (res) => res.arrayBuffer());
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user