GuidesPage Types
Table of Contents:
Static Page
ShipFast comes with many components to help you build SEO-optimized pages (like a landing page) in no time.
- The
/components
folder contains all you need (hero, pricing, FAQ sections). Checkout each component docs. - The
/libs/seo.tsx
file helps you set SEO tags to better rank on Google. Make sure to customize SEO tags.
A simple landing page can done like this in the pages.tsx
file:
/app/page.tsx
1import { getSEOTags } from "@/libs/seo";
2
3export const metadata = getSEOTags({ canonicalUrlRelative: "/" });
4
5export default function Landing() {
6 return (
7 <>
8 <main className="min-h-screen p-12 pb-24 text-center" data-theme="dark">
9 <section className="max-w-xl mx-auto space-y-8">
10 <h1 className="text-3xl md:text-4xl font-extrabold">
11 Food recipes you'll love 🥦
12 </h1>
13
14 <p className="text-lg leading-relaxed text-base-content/80">
15 Our AI will generate recipes based on your preferences. New recipes
16 will be added every week!
17 </p>
18
19 <img
20 src="https://images.unsplash.com/photo-1518843875459-f738682238a6?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=3484&q=80"
21 alt="Vegetables"
22 width={500}
23 height={250}
24 className="rounded-lg mx-auto"
25 />
26
27 <button className="btn btn-primary btn-wide">Get started</button>
28 </section>
29 </main>
30 </>
31 );
32}
Private Page
Once user is authenticated, you can build private routes like a user dashboard, account, etc.
If you want to make protected API calls, follow this tutorial.
The layout.tsx
in /dashboard
ensures any pages & subpages are private. If the user is not authenticated, he'll be redirected to the login page (see auth
in config.ts
).
NextAuth & Mongo
Here's an example of a simple user dashboard showing private user data in a server component:
/app/dashboard/page.tsx
1import { getServerSession } from "next-auth";
2import { authOptions } from "@/libs/next-auth";
3import connectMongo from "@/libs/mongoose";
4import User from "@/models/User";
5
6export default async function Dashboard() {
7 await connectMongo();
8 const session = await getServerSession(authOptions);
9 const user = await User.findById(session.user.id);
10
11 return (
12 <>
13 <main className="min-h-screen p-8 pb-24">
14 <section className="max-w-xl mx-auto space-y-8">
15 <h1 className="text-3xl md:text-4xl font-extrabold">
16 User Dashboard
17 </h1>
18 <p>Welcome {user.name} 👋</p>
19 <p>Your email is {user.email}</p>
20 </section>
21 </main>
22 </>
23 );
24}
Supabase
Here's an example of a simple user dashboard showing private user data in a server component:
/app/dashboard/page.tsx
1import { cookies } from "next/headers";
2import { createServerComponentClient } from "@supabase/auth-helpers-nextjs";
3
4export const dynamic = "force-dynamic";
5
6// This is a private page: It's protected by the layout.tsx component which ensures the user is authenticated.
7// It's a server compoment which means you can fetch data (like the user profile) before the page is rendered.
8export default async function Dashboard() {
9 const supabase = createServerComponentClient({ cookies });
10 const { data } = await supabase.from("todos").select();
11
12 return (
13 <main className="min-h-screen p-8 pb-24">
14 <section className="max-w-xl mx-auto space-y-8">
15 <h1 className="text-3xl md:text-4xl font-extrabold">Private Page</h1>
16
17 {/* You will only see something if you create an SQL table called todos with at least 1 row */}
18 <pre>{JSON.stringify(data, null, 2)}</pre>
19 </section>
20 </main>
21 );
22}