Skip to content

Commit 841619c

Browse files
authored
Subdomain Previews Implementation (#347)
1 parent dbbc887 commit 841619c

File tree

10 files changed

+65
-54
lines changed

10 files changed

+65
-54
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ https://github.com/vercel/platforms/assets/28986134/bd370257-0c27-4cf5-8a56-2858
3535
5. **Custom styles**: Custom fonts, 404 pages, favicons, sitemaps for each site via the [Next.js file-based Metadata API](https://nextjs.org/docs/app/api-reference/file-conventions/metadata)
3636
6. **Dynamic OG Cards**: Each blog post comes with a dynamic OG image powered by [@vercel/og](https://vercel.com/docs/concepts/functions/edge-functions/og-image-generation)
3737
7. **Dark Mode**: For a better user experience at night
38+
8. **Multi-tenant Preview URLs**: Preview changes to your client sites using [Vercel Preview URLs](https://vercel.com/docs/deployments/generated-urls). [Learn more](https://vercel.com/guides/nextjs-multi-tenant-application#3.-multi-tenant-preview-urls).
3839

3940
<picture>
4041
<source media="(prefers-color-scheme: dark)" srcset="https://images.ctfassets.net/e5382hct74si/k7XpXIE0rDsHCAYvkKhff/ff44c07588068d8fefa334cd6a318c8a/CleanShot_2023-07-05_at_08.39.02.png">
@@ -83,7 +84,7 @@ These are content-heavy platforms (blogs) with simple, standardized page layouts
8384
> “With Vercel, we spend less time managing our infrastructure and more time delivering value to our users.” — Sandeep Panda, Co-founder, Hashnode
8485
8586
1. [Hashnode](https://hashnode.com)
86-
2. [Mirror.xyz](https://mirror.xyz/)
87+
2. [Mintlify](https://mintlify.com/)
8788
3. [Read.cv](https://read.cv/)
8889

8990
### 2. Website & e-commerce store builders
@@ -104,7 +105,7 @@ With Vercel and Next.js, platforms like [Instatus](https://instatus.com) are abl
104105

105106
1. [Instatus](https://instatus.com/)
106107
2. [Cal.com](https://cal.com/)
107-
3. [Dub](https://dub.sh/)
108+
3. [Dub](https://dub.co/)
108109

109110
## Built on open source
110111

app/[domain]/[slug]/opengraph-image.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable @next/next/no-img-element */
22

33
import { truncate } from "@/lib/utils";
4-
import { ImageResponse } from "next/server";
4+
import { ImageResponse } from "next/og";
55
import { sql } from "@vercel/postgres";
66

77
export const runtime = "edge";

components/form/delete-post-form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import LoadingDots from "@/components/icons/loading-dots";
44
import { cn } from "@/lib/utils";
55
import { useParams, useRouter } from "next/navigation";
6-
import { experimental_useFormStatus as useFormStatus } from "react-dom";
6+
import { useFormStatus } from "react-dom";
77
import { toast } from "sonner";
88
import { deletePost } from "@/lib/actions";
99
import va from "@vercel/analytics";

components/form/delete-site-form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import LoadingDots from "@/components/icons/loading-dots";
44
import { cn } from "@/lib/utils";
55
import { useParams, useRouter } from "next/navigation";
6-
import { experimental_useFormStatus as useFormStatus } from "react-dom";
6+
import { useFormStatus } from "react-dom";
77
import { toast } from "sonner";
88
import { deleteSite } from "@/lib/actions";
99
import va from "@vercel/analytics";

components/form/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import LoadingDots from "@/components/icons/loading-dots";
44
import { cn } from "@/lib/utils";
55
import { useSession } from "next-auth/react";
66
import { useParams, useRouter } from "next/navigation";
7-
import { experimental_useFormStatus as useFormStatus } from "react-dom";
7+
import { useFormStatus } from "react-dom";
88
import { toast } from "sonner";
99
import DomainStatus from "./domain-status";
1010
import DomainConfiguration from "./domain-configuration";

components/modal/create-site.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { toast } from "sonner";
44
import { createSite } from "@/lib/actions";
55
import { useRouter } from "next/navigation";
6-
import { experimental_useFormStatus as useFormStatus } from "react-dom";
6+
import { useFormStatus } from "react-dom";
77
import { cn } from "@/lib/utils";
88
import LoadingDots from "@/components/icons/loading-dots";
99
import { useModal } from "./provider";

components/report-abuse.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { cn } from "@/lib/utils";
44
import { AlertTriangle } from "lucide-react";
55
import { useParams } from "next/navigation";
66
import { useState } from "react";
7-
import { experimental_useFormStatus as useFormStatus } from "react-dom";
7+
import { useFormStatus } from "react-dom";
88
import LoadingDots from "./icons/loading-dots";
99
import va from "@vercel/analytics";
1010
import { toast } from "sonner";

middleware.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,20 @@ export default async function middleware(req: NextRequest) {
1818
const url = req.nextUrl;
1919

2020
// Get hostname of request (e.g. demo.vercel.pub, demo.localhost:3000)
21-
const hostname = req.headers
21+
let hostname = req.headers
2222
.get("host")!
2323
.replace(".localhost:3000", `.${process.env.NEXT_PUBLIC_ROOT_DOMAIN}`);
2424

25+
// special case for Vercel preview deployment URLs
26+
if (
27+
hostname.includes("---") &&
28+
hostname.endsWith(`.${process.env.NEXT_PUBLIC_VERCEL_DEPLOYMENT_SUFFIX}`)
29+
) {
30+
hostname = `${hostname.split("---")[0]}.${
31+
process.env.NEXT_PUBLIC_ROOT_DOMAIN
32+
}`;
33+
}
34+
2535
const searchParams = req.nextUrl.searchParams.toString();
2636
// Get the pathname of the request (e.g. /, /about, /blog/first-post)
2737
const path = `${url.pathname}${

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"js-cookie": "^3.0.5",
2727
"lucide-react": "^0.244.0",
2828
"nanoid": "^4.0.2",
29-
"next": "13.5.5-canary.0",
29+
"next": "14.0.1",
3030
"next-auth": "4.23.1",
3131
"next-mdx-remote": "^4.4.1",
3232
"novel": "^0.1.22",
@@ -49,7 +49,7 @@
4949
"@types/js-cookie": "^3.0.3",
5050
"@types/node": "^20.4.1",
5151
"@types/react": "^18.2.14",
52-
"@types/react-dom": "^18.2.6",
52+
"@types/react-dom": "^18.2.15",
5353
"autoprefixer": "^10.4.14",
5454
"eslint": "8.31.0",
5555
"eslint-config-next": "^13.4.9",

pnpm-lock.yaml

Lines changed: 43 additions & 43 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)