Pages
The Horizon Boilerplate offers a wide array of components, making it a breeze to construct SEO-optimized pages like a landing page.
Within the /components
folder there is everything, including components for the hero section, pricing, and FAQ sections. You can check all of our components here.
There are 2 ways of creating a page :
1. If you do not have to use functions or components that require client rendering, you can simply import the sections you need like in the example below:
app/page.tsx
import {
getSession,
getSubscription,
getActiveProductsWithPrices,
} from '@/app/supabase-server';
import { FooterWebsite } from '@/components/footer/FooterWebsite';
import Faq from '@/components/landing/faq';
import FeatureOne from '@/components/landing/feature-one';
import FeatureThree from '@/components/landing/feature-three';
import FeatureTwo from '@/components/landing/feature-two';
import FeaturesList from '@/components/landing/features-list';
import FirstSection from '@/components/landing/first-section';
import Hero from '@/components/landing/hero';
import Newsletter from '@/components/landing/newsletter';
import SecondSection from '@/components/landing/second-section';
import NavbarFixed from '@/components/navbar/NavbarFixed';
export default async function LandingPage() {
// The marked code represents the Supabase custom code that helps you integrate the login function,
// fetches user info, and checks for subscriptions.
const [session, products, subscription] = await Promise.all([
getSession(),
getActiveProductsWithPrices(),
getSubscription(),
]).then();
return (
<div>
<NavbarFixed session={session} />
<div className="relative flex h-full min-h-screen flex-col items-center overflow-hidden">
<div className="relative flex w-full flex-col items-center justify-center pb-0 md:pb-[80px]">
<Hero />
<FeaturesList />
<FirstSection />
<SecondSection />
<FeatureOne />
<FeatureTwo />
<FeatureThree />
<Faq />
<Newsletter />
</div>
<FooterWebsite />
</div>
</div>
);
}
2. If you need a mix of Client and server components, you might want to follow the structure below:
app/pricing/page.tsx
import {
getSession,
getSubscription,
getActiveProductsWithPrices,
} from '@/app/supabase-server';
import Pricing from '@/components/pricing';
export default async function PricingPage() {
const [session, products, subscription] = await Promise.all([
getSession(),
getActiveProductsWithPrices(),
getSubscription(),
]);
return (
<Pricing
session={session}
user={session?.user}
products={products}
subscription={subscription}
/>
);
}
Then in components/pricing
you will have the page itself:
components/pricing/index.tsx
'use client';
import { FooterWebsite } from '../footer/FooterWebsite';
import Card from '@/components/card/Card';
import Faq from '@/components/landing/faq';
import InnerContent from '@/components/layout/innerContent';
import NavbarFixed from '@/components/navbar/NavbarFixed';
import { Database } from '@/types_db';
import { postData } from '@/utils/helpers';
import { getStripe } from '@/utils/stripe-client';
import { Session, User } from '@supabase/supabase-js';
import { useRouter } from 'next/navigation';
import React, { useState } from 'react';
import {
FaCcVisa,
FaCcMastercard,
FaCcPaypal,
FaCcAmex,
FaCcApplePay,
} from 'react-icons/fa';
import {
MdChevronRight,
MdCheckCircle,
MdAttachMoney,
MdLock,
MdOutlineDoDisturbOn,
} from 'react-icons/md';
export default function Pricing({
session,
user,
products,
subscription,
}: Props) {
const router = useRouter();
const [priceIdLoading, setPriceIdLoading] = useState<string>();
const handleCheckout = async (price: Price) => {
..................
};
const [version, setVersion] = useState('monthly');
return (
<div
className="relative w-full flex-col overflow-hidden bg-cover pt-[120px] md:pt-[220px]"
id="pricing"
>
<NavbarFixed session={session} />
<InnerContent extra="max-w-full md:max-w-full pb-[60px] md:pb-[100px]">
..................................
</InnerContent>
<Faq />
<FooterWebsite />
</div>
);
}