refactor: replace siteConfig.url with dynamic base URL generation
- Replace hardcoded site URL references with dynamic getBaseUrl() function - Remove unnecessary keywords and author fields from siteConfig - Simplify metadata generation in constructMetadata function - Add EMAIL_FROM constant for email configuration - Improve type definitions and remove redundant configurations
This commit is contained in:
parent
8d54beee58
commit
df17877ede
@ -7,6 +7,7 @@ import { siteConfig } from '@/config/site';
|
||||
import { constructMetadata } from '@/lib/metadata';
|
||||
import type { Metadata } from 'next';
|
||||
import { NextPageProps } from '@/types/next-page-props';
|
||||
import { getBaseUrl } from '@/lib/urls/get-base-url';
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
@ -28,7 +29,7 @@ export async function generateMetadata({
|
||||
return;
|
||||
}
|
||||
|
||||
const ogImageUrl = new URL(`${siteConfig.url}/api/og`);
|
||||
const ogImageUrl = new URL(`${getBaseUrl()}/api/og`);
|
||||
ogImageUrl.searchParams.append('title', category.name);
|
||||
ogImageUrl.searchParams.append('description', category.description || '');
|
||||
ogImageUrl.searchParams.append('type', 'Blog Category');
|
||||
@ -36,7 +37,7 @@ export async function generateMetadata({
|
||||
return constructMetadata({
|
||||
title: `${category.name}`,
|
||||
description: category.description,
|
||||
canonicalUrl: `${siteConfig.url}/blog/category/${slug}`,
|
||||
canonicalUrl: `${getBaseUrl()}/blog/category/${slug}`,
|
||||
// image: ogImageUrl.toString(),
|
||||
});
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { ErrorCard } from '@/components/auth/error-card';
|
||||
import { siteConfig } from '@/config/site';
|
||||
import { getBaseUrl } from '@/lib/urls/get-base-url';
|
||||
import { constructMetadata } from '@/lib/metadata';
|
||||
import { Routes } from '@/routes';
|
||||
|
||||
export const metadata = constructMetadata({
|
||||
title: 'Auth Error',
|
||||
description: 'Auth Error',
|
||||
canonicalUrl: `${siteConfig.url}${Routes.AuthError}`,
|
||||
description: 'Auth Error',
|
||||
canonicalUrl: `${getBaseUrl()}${Routes.AuthError}`,
|
||||
});
|
||||
|
||||
const AuthErrorPage = () => {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { ForgotPasswordForm } from '@/components/auth/forgot-password-form';
|
||||
import { siteConfig } from '@/config/site';
|
||||
import { getBaseUrl } from '@/lib/urls/get-base-url';
|
||||
import { constructMetadata } from '@/lib/metadata';
|
||||
import { Routes } from '@/routes';
|
||||
|
||||
export const metadata = constructMetadata({
|
||||
title: 'Forgot Password',
|
||||
description: 'Forgot your password? Reset it.',
|
||||
canonicalUrl: `${siteConfig.url}${Routes.ForgotPassword}`,
|
||||
canonicalUrl: `${getBaseUrl()}${Routes.ForgotPassword}`,
|
||||
});
|
||||
|
||||
const ForgotPasswordPage = () => {
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { LoginForm } from '@/components/auth/login-form';
|
||||
import { siteConfig } from '@/config/site';
|
||||
import { LocaleLink } from '@/i18n/navigation';
|
||||
import { constructMetadata } from '@/lib/metadata';
|
||||
import { getBaseUrl } from '@/lib/urls/get-base-url';
|
||||
import { Routes } from '@/routes';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
export const metadata = constructMetadata({
|
||||
title: 'Login',
|
||||
description: 'Login to your account',
|
||||
canonicalUrl: `${siteConfig.url}${Routes.Login}`,
|
||||
canonicalUrl: `${getBaseUrl()}${Routes.Login}`,
|
||||
});
|
||||
|
||||
const LoginPage = () => {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { RegisterForm } from '@/components/auth/register-form';
|
||||
import { siteConfig } from '@/config/site';
|
||||
import { constructMetadata } from '@/lib/metadata';
|
||||
import { getBaseUrl } from '@/lib/urls/get-base-url';
|
||||
import { Routes } from '@/routes';
|
||||
|
||||
export const metadata = constructMetadata({
|
||||
title: 'Register',
|
||||
description: 'Create an account to get started',
|
||||
canonicalUrl: `${siteConfig.url}${Routes.Register}`,
|
||||
canonicalUrl: `${getBaseUrl()}${Routes.Register}`,
|
||||
});
|
||||
|
||||
const RegisterPage = () => {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { ResetPasswordForm } from '@/components/auth/reset-password-form';
|
||||
import { siteConfig } from '@/config/site';
|
||||
import { constructMetadata } from '@/lib/metadata';
|
||||
import { getBaseUrl } from '@/lib/urls/get-base-url';
|
||||
|
||||
export const metadata = constructMetadata({
|
||||
title: 'Reset Password',
|
||||
description: 'Set a new password',
|
||||
canonicalUrl: `${siteConfig.url}/auth/reset-password`,
|
||||
canonicalUrl: `${getBaseUrl()}/auth/reset-password`,
|
||||
});
|
||||
|
||||
const ResetPasswordPage = () => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { siteConfig } from '@/config/site';
|
||||
import { getBaseUrl } from '@/lib/urls/get-base-url';
|
||||
import type { MetadataRoute } from 'next';
|
||||
|
||||
/**
|
||||
@ -10,6 +10,6 @@ export default function robots(): MetadataRoute.Robots {
|
||||
userAgent: '*',
|
||||
allow: '/',
|
||||
},
|
||||
sitemap: `${siteConfig.url}/sitemap.xml`,
|
||||
sitemap: `${getBaseUrl()}/sitemap.xml`,
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { getBaseUrl } from '@/lib/urls/get-base-url';
|
||||
import type { SiteConfig } from '@/types';
|
||||
|
||||
export const siteConfig: SiteConfig = {
|
||||
@ -7,15 +6,6 @@ export const siteConfig: SiteConfig = {
|
||||
tagline: 'Make AI SaaS in hours, simply and effortlessly',
|
||||
description:
|
||||
'MkSaaS is the best AI SaaS boilerplate. Make AI SaaS in hours, simply and effortlessly',
|
||||
keywords: [
|
||||
'SaaS',
|
||||
'SaaS Website',
|
||||
'SaaS Website Template',
|
||||
'SaaS Website Boilerplate',
|
||||
'SaaS Website Builder',
|
||||
],
|
||||
author: 'MkSaaS',
|
||||
url: getBaseUrl(),
|
||||
image: `${getBaseUrl()}/og.png`,
|
||||
image: `og.png`,
|
||||
mail: 'support@mksaas.com',
|
||||
};
|
||||
|
@ -2,7 +2,6 @@ import { createAuthClient } from 'better-auth/react';
|
||||
import { adminClient } from 'better-auth/client/plugins';
|
||||
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: process.env.NEXT_PUBLIC_BASE_URL!,
|
||||
plugins: [
|
||||
// https://www.better-auth.com/docs/plugins/admin#add-the-client-plugin
|
||||
adminClient(),
|
||||
|
@ -1,14 +1,12 @@
|
||||
import { siteConfig } from '@/config/site';
|
||||
import db from '@/db/index';
|
||||
import { account, session, user, verification } from '@/db/schema';
|
||||
import { send } from '@/mail/send';
|
||||
import { getLocaleFromRequest } from '@/lib/utils';
|
||||
import { send } from '@/mail/send';
|
||||
import { betterAuth } from 'better-auth';
|
||||
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
|
||||
import { admin } from 'better-auth/plugins';
|
||||
|
||||
const from = process.env.RESEND_FROM || 'delivered@resend.dev';
|
||||
|
||||
export const auth = betterAuth({
|
||||
appName: siteConfig.name,
|
||||
database: drizzleAdapter(db, {
|
||||
@ -30,10 +28,9 @@ export const auth = betterAuth({
|
||||
maxAge: 5 * 60, // Cache duration in seconds
|
||||
},
|
||||
// https://www.better-auth.com/docs/concepts/session-management#session-expiration
|
||||
expiresIn: 60 * 60 * 24 * 7, // 7 days
|
||||
updateAge: 60 * 60 * 24, // every 1 day the session expiration is updated
|
||||
// https://www.better-auth.com/docs/concepts/session-management#session-freshness
|
||||
freshAge: 60 * 5, // the session is fresh if created within the last 5 minutes
|
||||
expiresIn: 60 * 60 * 24 * 7,
|
||||
updateAge: 60 * 60 * 24,
|
||||
freshAge: 60 * 5,
|
||||
},
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
|
@ -1 +1,3 @@
|
||||
export const POSTS_PER_PAGE = 6;
|
||||
|
||||
export const EMAIL_FROM = process.env.EMAIL_FROM;
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { siteConfig } from '@/config/site';
|
||||
import type { Metadata } from 'next';
|
||||
import { getBaseUrl } from './urls/get-base-url';
|
||||
|
||||
/**
|
||||
* Construct the metadata object for the current page (in docs/guides)
|
||||
@ -18,16 +19,11 @@ export function constructMetadata({
|
||||
noIndex?: boolean;
|
||||
} = {}): Metadata {
|
||||
const fullTitle = title ? `${title} - ${siteConfig.title}` : siteConfig.title;
|
||||
const ogImageUrl = new URL(`${getBaseUrl()}/${image}`);
|
||||
|
||||
return {
|
||||
title: fullTitle,
|
||||
description,
|
||||
keywords: siteConfig.keywords,
|
||||
creator: siteConfig.author,
|
||||
authors: [
|
||||
{
|
||||
name: siteConfig.author,
|
||||
},
|
||||
],
|
||||
alternates: canonicalUrl
|
||||
? {
|
||||
canonical: canonicalUrl,
|
||||
@ -36,27 +32,26 @@ export function constructMetadata({
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
locale: 'en_US',
|
||||
url: siteConfig.url,
|
||||
url: getBaseUrl(),
|
||||
title: fullTitle,
|
||||
description,
|
||||
siteName: title,
|
||||
images: [image],
|
||||
images: [ogImageUrl.toString()],
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
title: fullTitle,
|
||||
description,
|
||||
images: [image],
|
||||
site: siteConfig.url,
|
||||
creator: siteConfig.author,
|
||||
images: [ogImageUrl.toString()],
|
||||
site: getBaseUrl(),
|
||||
},
|
||||
icons: {
|
||||
icon: '/favicon.ico',
|
||||
shortcut: '/favicon-32x32.png',
|
||||
apple: '/apple-touch-icon.png',
|
||||
},
|
||||
metadataBase: new URL(siteConfig.url),
|
||||
manifest: `${siteConfig.url}/site.webmanifest`,
|
||||
metadataBase: new URL(getBaseUrl()),
|
||||
manifest: `${getBaseUrl()}/site.webmanifest`,
|
||||
...(noIndex && {
|
||||
robots: {
|
||||
index: false,
|
||||
|
@ -6,15 +6,17 @@ import type { BaseMailProps } from '@/mail/types';
|
||||
import { Text } from '@react-email/components';
|
||||
import { createTranslator } from 'use-intl/core';
|
||||
|
||||
type ForgotPasswordProps = {
|
||||
url: string;
|
||||
name: string;
|
||||
} & BaseMailProps;
|
||||
|
||||
export function ForgotPassword({
|
||||
url,
|
||||
name,
|
||||
locale,
|
||||
messages,
|
||||
}: {
|
||||
url: string;
|
||||
name: string;
|
||||
} & BaseMailProps) {
|
||||
}: ForgotPasswordProps) {
|
||||
const t = createTranslator({
|
||||
locale,
|
||||
messages,
|
||||
|
@ -6,15 +6,17 @@ import type { BaseMailProps } from '@/mail/types';
|
||||
import { Text } from '@react-email/components';
|
||||
import { createTranslator } from 'use-intl/core';
|
||||
|
||||
type VerifyEmailProps = {
|
||||
url: string;
|
||||
name: string;
|
||||
} & BaseMailProps;
|
||||
|
||||
export function VerifyEmail({
|
||||
url,
|
||||
name,
|
||||
locale,
|
||||
messages,
|
||||
}: {
|
||||
url: string;
|
||||
name: string;
|
||||
} & BaseMailProps) {
|
||||
}: VerifyEmailProps) {
|
||||
const t = createTranslator({
|
||||
locale,
|
||||
messages,
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { EMAIL_FROM } from '@/lib/constants';
|
||||
import { Resend } from 'resend';
|
||||
import { SendEmailHandler } from '@/mail/types';
|
||||
|
||||
@ -11,7 +12,7 @@ export const sendEmail: SendEmailHandler = async ({ to, subject, html }) => {
|
||||
Authorization: `Bearer ${process.env.RESEND_API_KEY}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
from: process.env.RESEND_FROM,
|
||||
from: EMAIL_FROM,
|
||||
to,
|
||||
subject,
|
||||
html,
|
||||
|
@ -10,6 +10,9 @@ export interface EmailParams {
|
||||
|
||||
export type SendEmailHandler = (params: EmailParams) => Promise<void>;
|
||||
|
||||
/**
|
||||
* Mail provider, currently only Resend is supported
|
||||
*/
|
||||
export interface MailProvider {
|
||||
send: SendEmailHandler;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { MetadataRoute } from 'next';
|
||||
import { routing, Locale } from '@/i18n/routing';
|
||||
import { getLocalePathname } from '@/i18n/navigation';
|
||||
import { siteConfig } from './config/site';
|
||||
import { getBaseUrl } from './lib/urls/get-base-url';
|
||||
|
||||
/**
|
||||
* https://github.com/javayhu/cnblocks/blob/main/app/sitemap.ts
|
||||
@ -29,5 +29,5 @@ function getEntries(href: Href) {
|
||||
|
||||
function getUrl(href: Href, locale: Locale) {
|
||||
const pathname = getLocalePathname({ locale, href });
|
||||
return siteConfig.url + pathname;
|
||||
return getBaseUrl() + pathname;
|
||||
}
|
||||
|
3
src/types/index.d.ts
vendored
3
src/types/index.d.ts
vendored
@ -9,9 +9,6 @@ export type SiteConfig = {
|
||||
title: string;
|
||||
tagline: string;
|
||||
description: string;
|
||||
keywords: string[];
|
||||
author: string;
|
||||
url: string;
|
||||
image: string;
|
||||
mail: string;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user