Skip to content

Commit

Permalink
Improved placeholder page for custom domains root page
Browse files Browse the repository at this point in the history
  • Loading branch information
steven-tey committed Dec 24, 2022
1 parent 570eb62 commit 7c71d62
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 75 deletions.
9 changes: 4 additions & 5 deletions components/app/welcome/interim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import { Dispatch, SetStateAction, useState } from "react";
import { motion } from "framer-motion";
import BlurImage from "@/components/shared/blur-image";
import { Logo } from "@/components/shared/icons";
import { STAGGER_CHILD_VARIANTS } from "@/lib/constants";

export default function Interim({
setState,
staggerChildVariants,
}: {
setState: Dispatch<SetStateAction<string>>;
staggerChildVariants: any;
}) {
return (
<motion.div
Expand All @@ -29,7 +28,7 @@ export default function Interim({
transition={{ duration: 0.5, type: "spring" }}
>
<motion.div
variants={staggerChildVariants}
variants={STAGGER_CHILD_VARIANTS}
className="flex flex-col items-center space-y-5 text-center"
>
<Logo className="h-11 w-11" />
Expand All @@ -39,7 +38,7 @@ export default function Interim({
</motion.div>
<motion.p
className="text-gray-600 transition-colors sm:text-lg"
variants={staggerChildVariants}
variants={STAGGER_CHILD_VARIANTS}
>
Have your own domain? Start creating branded short links for free.{" "}
<br className="hidden sm:block" />
Expand All @@ -55,7 +54,7 @@ export default function Interim({
domain to create short links.
</motion.p>
<motion.div
variants={staggerChildVariants}
variants={STAGGER_CHILD_VARIANTS}
className="grid w-full grid-cols-1 divide-y divide-gray-100 rounded-md border border-gray-200 bg-white md:grid-cols-2 md:divide-x"
>
<button
Expand Down
9 changes: 4 additions & 5 deletions components/app/welcome/intro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import Spline from "@splinetool/react-spline";
import { Dispatch, SetStateAction, useState } from "react";
import { useDebounce } from "use-debounce";
import { motion } from "framer-motion";
import { STAGGER_CHILD_VARIANTS } from "@/lib/constants";

export default function Intro({
setState,
staggerChildVariants,
}: {
setState: Dispatch<SetStateAction<string>>;
staggerChildVariants: any;
}) {
const [loading, setLoading] = useState(true);
const onLoad = () => {
Expand Down Expand Up @@ -51,18 +50,18 @@ export default function Intro({
>
<motion.h1
className="font-display text-4xl font-bold text-gray-800 transition-colors sm:text-5xl"
variants={staggerChildVariants}
variants={STAGGER_CHILD_VARIANTS}
>
Welcome to Dub
</motion.h1>
<motion.p
className="max-w-md text-gray-600 transition-colors sm:text-lg"
variants={staggerChildVariants}
variants={STAGGER_CHILD_VARIANTS}
>
Dub gives you marketing superpowers with short links that stand out.
</motion.p>
<motion.button
variants={staggerChildVariants}
variants={STAGGER_CHILD_VARIANTS}
className="rounded-full bg-gray-800 px-10 py-2 font-medium text-white transition-colors hover:bg-black"
onClick={() => setState("interim")}
>
Expand Down
14 changes: 4 additions & 10 deletions components/layout/home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { ReactNode, useEffect, useState } from "react";
import { ReactNode } from "react";
import { useSession } from "next-auth/react";
import { Github, Logo, Twitter } from "@/components/shared/icons";
import Meta from "../meta";
Expand All @@ -22,20 +22,14 @@ export default function HomeLayout({
const { data: session, status } = useSession();
const router = useRouter();
const { key } = router.query as { key?: string };

const [hostname, setHostname] = useState("dub.sh");
useEffect(() => {
setHostname(window.location.origin);
}, []);

return (
<div className="flex min-h-screen flex-col justify-between">
<Meta {...meta} />
<div className={`${key ? "bg-gray-50" : ""} z-20`}>
<div className="mx-auto max-w-screen-xl px-5 md:px-20">
<div className="flex h-16 items-center justify-between">
<div className="flex items-center">
<Link href={hostname === "dub.sh" ? "/" : `https://dub.sh/`}>
<Link href="/">
<Image
src="/_static/logotype.svg"
alt="Dub.sh logo"
Expand Down Expand Up @@ -69,12 +63,12 @@ export default function HomeLayout({
</div>
</div>
{children}
<div className="z-10 flex h-20 items-center justify-center space-x-12 border-t border-gray-200">
<div className="z-10 flex h-20 items-center justify-center space-x-12 border-t border-gray-200 bg-white">
<a href="https://twitter.com/dubdotsh" target="_blank" rel="noreferrer">
<span className="sr-only">Twitter</span>
<Twitter className="h-6 w-6 text-gray-600" />
</a>
<Link href={hostname === "https://dub.sh" ? "/" : `https://dub.sh/`}>
<Link href="/">
<span className="sr-only">Dub.sh Logo</span>
<Logo className="h-7 w-7 text-gray-600" />
</Link>
Expand Down
6 changes: 5 additions & 1 deletion lib/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ export const FRAMER_MOTION_LIST_ITEM_VARIANTS = {
show: { scale: 1, opacity: 1, transition: { type: "spring" } },
};

export const STAGGER_CHILD_VARIANTS = {
hidden: { opacity: 0, y: 20 },
show: { opacity: 1, y: 0, transition: { duration: 0.4, type: "spring" } },
};

export const SWIPE_REVEAL_ANIMATION_SETTINGS = {
initial: { height: 0 },
animate: { height: "auto" },
Expand Down Expand Up @@ -64,7 +69,6 @@ export const RESERVED_KEYS = new Set([
"auth",
"pricing",
"about",
"placeholder",
"metatags",
"blog",
"careers",
Expand Down
2 changes: 1 addition & 1 deletion lib/middleware/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default async function RootMiddleware(
}
} else {
// rewrite to root page unless the user defines a site to redirect to
return NextResponse.next();
return NextResponse.rewrite(new URL(`/_root/${domain}`, req.url));
}
}
}
6 changes: 3 additions & 3 deletions middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ export const config = {
/*
* Match all paths except for:
* 1. /api/ routes
* 2. /_next (Next.js internals)
* 3. /_proxy & /_auth (special pages for OG tag proxying and password protection)
* 2. /_next/ (Next.js internals)
* 3. /_proxy/, /_auth/, /_root/ (special pages for OG tags proxying, password protection, and placeholder _root pages)
* 4. /_static (inside /public)
* 5. /_vercel (Vercel internals)
* 6. all root files inside /public (e.g. /favicon.ico)
*/
"/((?!api/|_next|_proxy|_auth|_static|_vercel|[\\w-]+\\.\\w+).*)",
"/((?!api/|_next/|_proxy/|_auth/|_root/|_static|_vercel|[\\w-]+\\.\\w+).*)",
],
};

Expand Down
111 changes: 111 additions & 0 deletions pages/_root/[domain].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import prisma from "@/lib/prisma";
import Background from "@/components/shared/background";
import Meta from "@/components/layout/meta";
import { useState } from "react";
import { motion } from "framer-motion";
import { useDebounce } from "use-debounce";
import { STAGGER_CHILD_VARIANTS } from "@/lib/constants";
import Spline from "@splinetool/react-spline";
import { InlineSnippet } from "@/components/app/settings/custom-domain/domain-configuration";

export default function Placeholder({ domain }: { domain: string }) {
const [loading, setLoading] = useState(true);
const onLoad = () => {
setLoading(false);
};
// workarouond to avoid the blinking effect when Spline loads
const [opacity] = useDebounce(loading ? 0 : 1, 200);

const [showText] = useDebounce(loading ? false : true, 800);

return (
<div className="flex h-screen flex-col items-center">
<Meta
title={`${domain.toUpperCase()} - A Dub Custom Domain`}
description={`${domain.toUpperCase()} is a custom domain on Dub - an open-source link management tool for modern marketing teams to create, share, and track short links.`}
/>
<Background />
<motion.div
className="z-10"
exit={{ opacity: 0, scale: 0.95 }}
transition={{ duration: 0.5, type: "spring" }}
>
<div
className={`${
loading ? "scale-[25%] blur-md" : "scale-100 blur-0"
} mt-[7vh] h-[50vh] w-screen object-cover transition-all duration-1000`}
>
<Spline
onLoad={onLoad}
style={{ opacity: opacity }}
scene="https://prod.spline.design/cJkq6hsiUPNRHeMf/scene.splinecode"
/>
</div>
{showText && (
<motion.div
variants={{
show: {
transition: {
staggerChildren: 0.3,
},
},
}}
initial="hidden"
animate="show"
className="mx-5 flex flex-col items-center space-y-10 text-center sm:mx-auto"
>
<motion.h1
className="font-display text-4xl font-bold text-gray-800 transition-colors sm:text-5xl"
variants={STAGGER_CHILD_VARIANTS}
>
Welcome to Dub
</motion.h1>
<motion.p
className="max-w-xl text-gray-600 transition-colors sm:text-lg"
variants={STAGGER_CHILD_VARIANTS}
>
<InlineSnippet>{domain}</InlineSnippet> is a custom domain on Dub
- a link management tool for modern marketing teams to create,
share, and track short links.
</motion.p>
<motion.a
variants={STAGGER_CHILD_VARIANTS}
href={`https://dub.sh?utm_source=${domain}&utm_medium=referral&utm_campaign=custom-domain`}
className="rounded-full bg-gray-800 px-10 py-2 font-medium text-white transition-colors hover:bg-black"
>
Create Your Free Branded Link
</motion.a>
</motion.div>
)}
</motion.div>
</div>
);
}

export const getStaticPaths = async () => {
const domains = await prisma.project.findMany({
where: {
domainVerified: true,
},
select: {
domain: true,
},
});
return {
paths: domains.map(({ domain }) => ({
params: {
domain,
},
})),
fallback: "blocking",
};
};

export const getStaticProps = async (context) => {
const { domain } = context.params;
return {
props: {
domain,
},
};
};
29 changes: 5 additions & 24 deletions pages/app/welcome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@ import Background from "@/components/shared/background";
import Intro from "@/components/app/welcome/intro";
import Interim from "@/components/app/welcome/interim";
import { AnimatePresence } from "framer-motion";
import { Suspense, useEffect, useState } from "react";
import { useEffect, useState } from "react";
import { useAddProjectModal } from "@/components/app/modals/add-project-modal";
import { useAddEditLinkModal } from "@/components/app/modals/add-edit-link-modal";
import Meta from "@/components/layout/meta";

const staggerChildVariants = {
hidden: { opacity: 0, y: 20 },
show: { opacity: 1, y: 0, transition: { duration: 0.4, type: "spring" } },
};

export default function Welcome() {
const [state, setState] = useState("intro");

Expand Down Expand Up @@ -41,24 +36,10 @@ export default function Welcome() {
<Background />
<AddProjectModal />
<AddEditLinkModal />
<Suspense>
<AnimatePresence mode="wait">
{state === "intro" && (
<Intro
key="intro"
setState={setState}
staggerChildVariants={staggerChildVariants}
/>
)}
{state === "interim" && (
<Interim
key="interim"
setState={setState}
staggerChildVariants={staggerChildVariants}
/>
)}
</AnimatePresence>
</Suspense>
<AnimatePresence mode="wait">
{state === "intro" && <Intro key="intro" setState={setState} />}
{state === "interim" && <Interim key="interim" setState={setState} />}
</AnimatePresence>
</div>
);
}
26 changes: 0 additions & 26 deletions pages/placeholder/[[...domain]].tsx

This file was deleted.

0 comments on commit 7c71d62

Please sign in to comment.