A template for site builders and low-code tools.

Overview

Platforms Starter Kit

The all-in-one starter kit
for building platforms on Vercel.

Introduction · Guide · Demo · Kitchen Sink · Contributing


Deploy Your Own

Read the guide to learn how to deploy your own version of this template.

Introduction

Multi-tenant applications serve multiple customers across different subdomains/custom domains with a single unified codebase.

For example, our demo is a multi-tenant application:

Another example is Hashnode, a popular blogging platform. Each writer has their own unique .hashnode.dev subdomain for their blog:

Users can also map custom domains to their .hashnode.dev subdomain:

This repository makes it easier than ever for creators to build their own platform.

Template features

Forget manually setting up CNAME records, wrestling with DNS, or making custom server rewrite rules with NGINX. With Vercel and the Platforms Starter Kit, you can focus on building the next big thing.

  • Custom domains: Subdomain and custom domains support with Edge Functions and the Vercel Domains API.
  • Static generation with ISR: Performance without sacrificing personalization, by combining Incremental Static Regeneration (ISR) and Middleware. ISR allows you to create new content (with custom domains) on demand without needing to redeploy your application.
  • Uploading custom images: Allow your customers to upload custom thumbnail images with our Cloudinary integration.
  • Static tweets: Avoid Cumulative Layout Shift (CLS) from the native Twitter embed by using our static tweets implementation (supports image, video, gif, poll, retweets, quote retweets, and more).

Examples of platforms

Vercel customers like Hashnode, Super, and Cal.com are building scalable platforms on top of Vercel and Next.js. There are multiple types of platforms you can build with this starter kit:

1. Content creation platforms

These are content-heavy platforms (blogs) with simple, standardized page layouts and route structure.

“With Vercel, we spend less time managing our infrastructure and more time delivering value to our users.” — Sandeep Panda, Co-founder, Hashnode

  1. Hashnode
  2. Mirror.xyz
  3. Papyrus.so

2. Website & e-commerce store builders

No-code site builders with customizable pages.

By using Next.js and Vercel, Super has fast, globally distributed websites with a no-code editor (Notion). Their customers get all the benefits of Next.js (like Image Optimization) without touching any code.

  1. Super.so
  2. Typedream
  3. Makeswift

3. B2B2C platforms

Multi-tenant authentication, login, and access controls.

With Vercel and Next.js, platforms like Instatus are able to create status pages that are 10x faster than competitors.

  1. Instatus
  2. Cal.com
  3. DAO Central

Built on open source

This working demo site was built using the Platforms Starter Kit and:

We also have another example of the Platforms Starter Kit that uses Supabase for the database and Slate.js for the text editor.

Contributing

  • Start a discussion with a question, piece of feedback, or idea you want to share with the team.
  • Open an issue if you believe you've encountered a bug with the starter kit.

Author

License

The MIT License.


Comments
  • Convert to TypeScript

    Convert to TypeScript

    What

    This PR migrates the code base to using TypeScript, as recommended by @leerob in #3. It also includes a number of other changes, including the following:

    • Migrate entire codebase to TypeScript
    • Add global / reusable fetcher function (lib/fetcher)
    • Adds request methods bouncers to "most" API endpoints
    • Added @/types import alias
    • Added types/ directory for all custom types
    • Removed some unnecessary console.log's
    • Removed jsconfig.json
    • Minor api endpoint restructuring for domain endpoints
    • Renamed GitHub client ID/secret env vars to better fitting names
    • Lots of cleanup / code standard improvements
    • Move major API functionality to lib/ directory
    opened by NuroDev 21
  • Switch from Twitter to GitHub OAuth

    Switch from Twitter to GitHub OAuth

    Overall, GitHub OAuth has a lot fewer steps to get set up than Twitter OAuth. I think this would help those trying to get the project set up and running locally. Plus, with next-auth, you can always switch to other providers if you want.

    Thoughts?

    opened by leerob 10
  • Add error toasts on login page

    Add error toasts on login page

    What

    A nice improvement to offer out of the box would be error prompts for the login page (User can see if it's an issue with something they did, or a server-side issue, etc). Seeing as react-hot-toast is already used in other places, we could use that combined with next/router to check for any error parameters returned by next-auth

    opened by NuroDev 10
  • Twitter Auth Essential Access error

    Twitter Auth Essential Access error

    I'm getting the following error.

    [next-auth][error][OAUTH_V1_GET_ACCESS_TOKEN_ERROR] 
    https://next-auth.js.org/errors#oauth_v1_get_access_token_error undefined {
      statusCode: 403,
      data: '{"errors":[{"message":"You currently have Essential access which includes access to Twitter API v2 endpoints only. If you need access to this endpoint, you’ll need to apply for Elevated access via the Developer Portal. You can learn more here: https://developer.twitter.com/en/docs/twitter-api/getting-started/about-twitter-api#v2-access-leve","code":453}]}\n'
    }
    

    I am following along with the blog post but things do look different for me. For example, my Twitter dev dashboard does not have "enable 3-legged" option. Just the options in the screenshot below

    image

    I can't even get the login button to prompt for Twitter oAuth without changing the callback URL in step 13 from the blog post suggestion of 'http://localhost:3000/api/auth/callback/twitter' (does not work) to 'http://app.localhost:3000/api/auth/callback/twitter' (prompts but get console error above)

    If I follow the blog post exactly I get this

    [next-auth][error][GET_AUTHORIZATION_URL_ERROR] 
    https://next-auth.js.org/errors#get_authorization_url_error undefined {
      statusCode: 403,
      data: `<?xml version='1.0' encoding='UTF-8'?><errors><error code="415">Callback URL not approved for this client application. Approved callback URLs can be adjusted in your application settings</error></errors>`
    }
    [next-auth][error][SIGNIN_OAUTH_ERROR] 
    https://next-auth.js.org/errors#signin_oauth_error undefined {
      error: {
        statusCode: 403,
        data: `<?xml version='1.0' encoding='UTF-8'?><errors><error code="415">Callback URL not approved for this client application. Approved callback URLs can be adjusted in your application settings</error></errors>`
      },
      provider: {
        id: 'twitter',
        name: 'Twitter (Legacy)',
        type: 'oauth',
        version: '1.0A',
        authorization: { url: 'https://api.twitter.com/oauth/authenticate', params: {} },
        accessTokenUrl: 'https://api.twitter.com/oauth/access_token',
        requestTokenUrl: 'https://api.twitter.com/oauth/request_token',
        profileUrl: 'https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true',
        profile: [Function: profile],
        clientId: 'xxxx-removed-xxxx',
        clientSecret: 'xxxx-removed-xxxx',
        signinUrl: 'http://app.localhost:3000/api/auth/signin/twitter',
        callbackUrl: 'http://app.localhost:3000/api/auth/callback/twitter'
      },
      message: undefined
    }
    

    Any help or suggestions is appreciated

    opened by kgrady13 8
  • Build fails due to incompatible npm packages with React 18 (`next-mdx-remote`)

    Build fails due to incompatible npm packages with React 18 (`next-mdx-remote`)

    I'm trying to deploy this to Vercel, and it keeps failing when it gets to NPM build

    [07:35:06.182] Previous build cache not available [07:35:07.389] Cloning completed: 1.365s [07:35:07.667] Running "vercel build" [07:35:08.354] Vercel CLI 28.4.17 [07:35:08.802] Warning: Detected "engines": { "node": ">=14.0.0" } in your package.json that will automatically upgrade when a new major Node.js Version is released. Learn More: http://vercel.link/node-version [07:35:08.820] Installing dependencies... [07:35:10.147] npm ERR! code ERESOLVE [07:35:10.151] npm ERR! ERESOLVE could not resolve [07:35:10.151] npm ERR! [07:35:10.151] npm ERR! While resolving: [email protected] [07:35:10.151] npm ERR! Found: [email protected] [07:35:10.152] npm ERR! node_modules/react [07:35:10.152] npm ERR! react@"^18.2.0" from the root project [07:35:10.152] npm ERR! peer react@"^16 || ^17 || ^18" from @headlessui/[email protected] [07:35:10.152] npm ERR! node_modules/@headlessui/react [07:35:10.152] npm ERR! @headlessui/react@"^1.4.3" from the root project [07:35:10.152] npm ERR! 12 more (@vercel/analytics, next, next-auth, react-dom, ...) [07:35:10.152] npm ERR! [07:35:10.153] npm ERR! Could not resolve dependency: [07:35:10.153] npm ERR! peer react@">=16.x <=17.x" from [email protected] [07:35:10.153] npm ERR! node_modules/next-mdx-remote [07:35:10.156] npm ERR! next-mdx-remote@"^3.0.8" from the root project [07:35:10.156] npm ERR! [07:35:10.156] npm ERR! Conflicting peer dependency: [email protected] [07:35:10.156] npm ERR! node_modules/react [07:35:10.157] npm ERR! peer react@">=16.x <=17.x" from [email protected] [07:35:10.157] npm ERR! node_modules/next-mdx-remote [07:35:10.157] npm ERR! next-mdx-remote@"^3.0.8" from the root project [07:35:10.157] npm ERR! [07:35:10.157] npm ERR! Fix the upstream dependency conflict, or retry [07:35:10.157] npm ERR! this command with --force, or --legacy-peer-deps [07:35:10.157] npm ERR! to accept an incorrect (and potentially broken) dependency resolution. [07:35:10.158] npm ERR! [07:35:10.158] npm ERR! See /vercel/.npm/eresolve-report.txt for a full report. [07:35:10.158] [07:35:10.158] npm ERR! A complete log of this run can be found in: [07:35:10.158] npm ERR! /vercel/.npm/_logs/2022-11-16T07_35_09_253Z-debug-0.log [07:35:10.170] Warning: Retrying "Install Command" with --legacy-peer-deps which may accept a potentially broken dependency and slow install time. [07:35:41.225] [07:35:41.225] > postinstall [07:35:41.225] > prisma generate || true [07:35:41.226] [07:35:42.779] Prisma schema loaded from prisma/schema.prisma [07:35:44.509] [07:35:44.510] ✔ Generated Prisma Client (3.8.1 | library) to ./node_modules/@prisma/client in 213ms [07:35:44.510] You can now start using Prisma Client in your code. Reference: https://pris.ly/d/client [07:35:44.510] [07:35:44.510] import { PrismaClient } from '@prisma/client' [07:35:44.510] const prisma = new PrismaClient() [07:35:44.510] [07:35:44.615] [07:35:44.616] added 622 packages in 34s [07:35:44.616] [07:35:44.617] 221 packages are looking for funding [07:35:44.617] run npm fund for details [07:35:44.643] Detected Next.js version: 13.0.2 [07:35:44.651] Detected package-lock.json generated by npm 7+... [07:35:44.651] Running "npm run build" [07:35:45.066] [07:35:45.066] > prebuild [07:35:45.066] > prisma generate [07:35:45.066] [07:35:46.616] Prisma schema loaded from prisma/schema.prisma [07:35:48.383] [07:35:48.384] ✔ Generated Prisma Client (3.8.1 | library) to ./node_modules/@prisma/client in 236ms [07:35:48.384] You can now start using Prisma Client in your code. Reference: https://pris.ly/d/client [07:35:48.384] [07:35:48.384] import { PrismaClient } from '@prisma/client' [07:35:48.384] const prisma = new PrismaClient() [07:35:48.384] [07:35:48.534] ┌─────────────────────────────────────────────────────────┐ [07:35:48.535] │ Update available 3.8.1 -> 4.6.1 │ [07:35:48.536] │ │ [07:35:48.536] │ This is a major update - please follow the guide at │ [07:35:48.536] │ https://pris.ly/d/major-version-upgrade │ [07:35:48.536] │ │ [07:35:48.537] │ Run the following to update │ [07:35:48.537] │ npm i --save-dev prisma@latest │ [07:35:48.537] │ npm i @prisma/client@latest │ [07:35:48.537] └─────────────────────────────────────────────────────────┘ [07:35:48.548] [07:35:48.549] > build [07:35:48.549] > next build [07:35:48.549] [07:35:49.116] Attention: Next.js now collects completely anonymous telemetry regarding usage. [07:35:49.117] This information is used to shape Next.js' roadmap and prioritize features. [07:35:49.117] You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL: [07:35:49.117] https://nextjs.org/telemetry [07:35:49.117] [07:35:49.257] info - Linting and checking validity of types... [07:35:58.998] info - Creating an optimized production build... [07:36:27.886] info - Compiled successfully [07:36:27.887] info - Collecting page data... [07:36:28.569] Error: Cannot find module '@babel/core' [07:36:28.570] Require stack: [07:36:28.570] - /vercel/path0/node_modules/@babel/plugin-proposal-object-rest-spread/lib/index.js [07:36:28.570] - /vercel/path0/node_modules/@mdx-js/mdx/node_modules/remark-mdx/extract-imports-and-exports.js [07:36:28.570] - /vercel/path0/node_modules/@mdx-js/mdx/node_modules/remark-mdx/index.js [07:36:28.570] - /vercel/path0/node_modules/@mdx-js/mdx/index.js [07:36:28.571] - /vercel/path0/node_modules/next-mdx-remote/dist/serialize.js [07:36:28.571] - /vercel/path0/node_modules/next-mdx-remote/serialize.js [07:36:28.571] - /vercel/path0/.next/server/pages/_sites/[site]/[slug].js [07:36:28.571] - /vercel/path0/node_modules/next/dist/server/require.js [07:36:28.571] - /vercel/path0/node_modules/next/dist/server/load-components.js [07:36:28.572] - /vercel/path0/node_modules/next/dist/export/worker.js [07:36:28.572] - /vercel/path0/node_modules/next/dist/build/worker.js [07:36:28.572] - /vercel/path0/node_modules/next/dist/compiled/jest-worker/processChild.js [07:36:28.572] at Function.Module._resolveFilename (node:internal/modules/cjs/loader:985:15) [07:36:28.572] at Function.mod._resolveFilename (/vercel/path0/node_modules/next/dist/build/webpack/require-hook.js:23:32) [07:36:28.572] at Function.Module._load (node:internal/modules/cjs/loader:833:27) [07:36:28.573] at Module.require (node:internal/modules/cjs/loader:1057:19) [07:36:28.573] at require (node:internal/modules/cjs/helpers:103:18) [07:36:28.573] at Object. (/vercel/path0/node_modules/@babel/plugin-proposal-object-rest-spread/lib/index.js:12:13) [07:36:28.573] at Module._compile (node:internal/modules/cjs/loader:1155:14) [07:36:28.573] at Object.Module._extensions..js (node:internal/modules/cjs/loader:1209:10) [07:36:28.573] at Module.load (node:internal/modules/cjs/loader:1033:32) [07:36:28.573] at Function.Module._load (node:internal/modules/cjs/loader:868:12) { [07:36:28.574] code: 'MODULE_NOT_FOUND', [07:36:28.574] requireStack: [ [07:36:28.574] '/vercel/path0/node_modules/@babel/plugin-proposal-object-rest-spread/lib/index.js', [07:36:28.574] '/vercel/path0/node_modules/@mdx-js/mdx/node_modules/remark-mdx/extract-imports-and-exports.js', [07:36:28.576] '/vercel/path0/node_modules/@mdx-js/mdx/node_modules/remark-mdx/index.js', [07:36:28.576] '/vercel/path0/node_modules/@mdx-js/mdx/index.js', [07:36:28.576] '/vercel/path0/node_modules/next-mdx-remote/dist/serialize.js', [07:36:28.576] '/vercel/path0/node_modules/next-mdx-remote/serialize.js', [07:36:28.576] '/vercel/path0/.next/server/pages/_sites/[site]/[slug].js', [07:36:28.577] '/vercel/path0/node_modules/next/dist/server/require.js', [07:36:28.577] '/vercel/path0/node_modules/next/dist/server/load-components.js', [07:36:28.577] '/vercel/path0/node_modules/next/dist/export/worker.js', [07:36:28.577] '/vercel/path0/node_modules/next/dist/build/worker.js', [07:36:28.577] '/vercel/path0/node_modules/next/dist/compiled/jest-worker/processChild.js' [07:36:28.577] ] [07:36:28.578] } [07:36:28.578] [07:36:28.578] > Build error occurred [07:36:28.582] Error: Failed to collect page data for /_sites/[site]/[slug] [07:36:28.582] at /vercel/path0/node_modules/next/dist/build/utils.js:955:15 { [07:36:28.582] type: 'Error' [07:36:28.582] } [07:36:28.645] Error: Command "npm run build" exited with 1`

    any help with this?

    opened by dedicatedcloud 7
  • Revalidation is not working

    Revalidation is not working

    When I build locally by next build and next start I can revalidate and it works, however, when I deploy this to vercel it won't revalidate anymore.

    Weird is, that revalidation only works with /_sites/blog/{id} instead of /{id} even though the rewrite is set in middleware and the validation happens on blog.domain.com. I get "OK" on the /_site.. requests and failed to revalidate on everything else.

    When I revalidate after deploying (using /_sites/...) I can disable the cache and refresh the page and for a split second I see the new version but than it changes back to the old one.

    I use this for a fixed path blog so I changed the getStaticPaths/ Props:

    pages/_sites/[site]/index

    export const getStaticPaths = async () => {
      return { paths: [{ params: { site: "blog" }}], fallback: true }
    };
    
    export const getStaticProps = async ({
      params,
    }) => {
      const data = (await prisma.post.findMany({
        where: {
          published: true,
        },
        orderBy: {
          createdAt: "desc",
        },
      }));
    
      if (!data) return { notFound: true, revalidate: 10 };
    
      return {
        props: {
          stringifiedData: JSON.stringify({
            [...]
          }),
        },
        revalidate: 3600,
      };
    };
    

    pages/_sites/[site]/[slug]

    export const getStaticPaths = async () => {
      const posts = await prisma.post.findMany({
        select: {
          slug: true,
        },
      });
    
      const paths = posts.flatMap((post) => {
        return {
          params: {
            site: "blog",
            slug: post.slug,
          },
        };
      })
    
      return {
        paths,
        fallback: true,
      };
    };
    
    
    export const getStaticProps = async ({
      params,
    }) => {
      if (!params) throw new Error("No path parameters found");
    
      const { slug } = params;
    
      const data = (await prisma.post.findFirst({
        where: {
          slug
        }
      }));
    
      if (!data) return { notFound: true, revalidate: 10 };
    
      const [mdxSource, adjacentPosts] = await Promise.all([
        getMdxSource(data.content),
        prisma.post.findMany({
          where: {
            published: true,
            NOT: {
              id: data.id,
            },
          },
          select: {
            slug: true,
            title: true,
            createdAt: true,
            description: true,
            image: true,
            imageBlurhash: true,
          },
        }),
      ]);
    
      return {
        props: {
          stringifiedData: JSON.stringify({
            ...data,
            mdxSource,
          }),
          stringifiedAdjacentPosts: JSON.stringify(adjacentPosts),
        },
        revalidate: 3600,
      };
    };
    

    And middleware

    export const config = {
      matcher: [
        "/",
        "/([^/.]*)", // exclude `/public` files by matching all paths except for paths containing `.` (e.g. /logo.png)
        "/site/:path*",
        "/post/:path*",
        "/_sites/:path*",
      ],
    };
    
    export default function middleware(req) {
      // Clone the request url
      const url = req.nextUrl.clone();
      
      const { pathname } = req.nextUrl;
      
      const hostname = req.headers.get("host");
      if (!hostname)
        return new Response(null, {
          status: 400,
          statusText: "No hostname found in request headers",
        });
    
    
      const currentHost =
        process.env.NODE_ENV === "production" && process.env.VERCEL === "1"
          ? hostname
          .replace(`.domain.org`, "")
          .replace(`.###.vercel.app`, "")
          : hostname.replace(`.localhost:3000`, "");
    
      if(process.env.NODE_ENV !== "production") {
        if(pathname.startsWith(`/_templates`)) {
          url.pathname = pathname
          return NextResponse.rewrite(url);
        }
      }
    
      if (pathname.startsWith(`/_sites`) || pathname.startsWith(`/_templates`))
        return new Response(null, {
          status: 404,
        });
    
    
      if (!pathname.includes(".") && !pathname.startsWith("/api")) {
        if (currentHost === "app") {
          if (
            pathname === "/login" &&
            (req.cookies["next-auth.session-token"] ||
              req.cookies["__Secure-next-auth.session-token"])
          ) {
            url.pathname = "/";
            return NextResponse.redirect(url);
          }
    
          url.pathname = `/app${pathname}`;
          return NextResponse.rewrite(url);
        }
    
        if (
          hostname === "localhost:3000" ||
          hostname === "domain.org" ||
          hostname === "###.vercel.app"
        ) {
          url.pathname = `/home${url.pathname}`;
          return NextResponse.rewrite(url);
        }
    
        if(currentHost === "blog") {
          url.pathname = `/_sites/${currentHost}${url.pathname}`;
          return NextResponse.rewrite(url);
        }
        
        
        url.pathname = `/_templates/router`;
        return NextResponse.rewrite(url);
      }
    

    Any idea?

    opened by 0x6c23 7
  • Production subdomains have empty props from getStaticProps

    Production subdomains have empty props from getStaticProps

    I added some platforms code to my app and everything was working fine until recently and now my subdomains on my production domain don't work.

    Here's what my component looks like in /pages/_sites/[site]/index.js

    const Index = (props) => {
      const router = useRouter();
    
      if (router.isFallback) {
        return <h1>Loading...</h1>;
      }
      console.log("compoennt: ");
      console.log(typeof props.site);
      console.log({ props });
    
      if (!props.site) return <p>error...</p>;
      const site = JSON.parse(props.site);
      if (!site.site) return <p>error...</p>;
    ...
    

    On my production site I get an empty props:

    image

    But on localhost I get the information I expect:

    image

    And in my Vercel build logs, I console.log my getStaticPaths and getStaticProps and I see all the data I expect:

    image

    But when I visit my website like subdomain.leavewithaweb.site I see an empty props object and my site doesn't work or have the data even though it's building?

    It was working like a week ago then something happened and it stopped working.

    My _middleware.js

    export default function middleware(req) {
      // Clone the request url
      const url = req.nextUrl.clone();
    
      // Get pathname of request (e.g. /blog-slug)
      const { pathname } = req.nextUrl;
    
      // Get hostname of request (e.g. demo.vercel.pub)
      const hostname = req.headers.get("host");
      if (!hostname)
        return new Response(null, {
          status: 400,
          statusText: "No hostname found in request headers",
        });
    
      const currentHost =
        process.env.NODE_ENV === "production" && process.env.VERCEL === "1"
          ? // You have to replace ".vercel.pub" with your own domain if you deploy this example under your domain.
            // You can use wildcard subdomains on .vercel.app links that are associated with your Vercel team slug
            // in this case, our team slug is "platformize", thus *.platformize.vercel.app works
            hostname.replace(`.leavewithaweb.site`, "")
          : hostname.replace(`.localhost:3000`, "");
    
      if (pathname.startsWith(`/_sites`))
        return new Response(null, {
          status: 404,
        });
    
      if (!pathname.includes(".") && !pathname.startsWith("/api")) {
        if (hostname === "localhost:3000" || hostname === "leavewithaweb.site") {
          if (
            pathname === "/" &&
            (req.cookies["next-auth.session-token"] ||
              req.cookies["__Secure-next-auth.session-token"])
          ) {
            url.pathname = `/home`;
            return NextResponse.rewrite(url);
          } else if (pathname === "/") {
            url.pathname = `/home`;
            return NextResponse.rewrite(url);
          }
        } else {
          url.pathname = `/_sites/${currentHost}${pathname}`;
          return NextResponse.rewrite(url);
        }
      }
    }
    

    My getStaticPaths and getStaticProps

    export async function getStaticPaths() {
      const subdomains = await fetch(
        `${process.env.NEXT_PUBLIC_SERVER_URL}zzz`,
        {
          method: "GET",
        }
      ).then((res) => res.json());
    
      console.log(subdomains);
    
      if (subdomains.subdomains.length === 0) {
        return {
          paths: [],
          fallback: true,
        };
      } else {
        return {
          paths: subdomains.subdomains.map((subdomain) => {
            return {
              params: { site: subdomain },
            };
          }),
          fallback: "blocking",
        };
      }
    }
    
    export async function getStaticProps({ params: { site } }) {
      const siteRes = await fetch(
        `${process.env.NEXT_PUBLIC_SERVER_URL}/zzz`,
        {
          method: "GET",
        }
      ).then((res) => res.json());
    
      console.log(siteRes);
    
      return {
        props: {
          site: JSON.stringify(siteRes),
        },
        revalidate: 10,
      };
    }
    
    opened by albertkimdev 7
  • How the On-demand ISR work for multiple subdomains?

    How the On-demand ISR work for multiple subdomains?

    I noticed a great feature On-demand ISR, but I'm not sure how to make it work for multiple subdomains. I read the source code of this repo, but the usage is:

    res.unstable_revalidate(urlPath);
    

    What if two sites have the same urlPath? For example alice.github.com/hello and bob.github.com/hello

    opened by futantan 6
  • fix: next-mdx-remote type error

    fix: next-mdx-remote type error

    • Fixes a type error with replaceLinks. When replacing native elements, like a, the prop types of your custom component have to match the underlying types
    • removes gray-matter, which appears to be unused and next-mdx-remote also provides frontmatter parsing
    • Removes an extra remark pass when serializing content, instead passes the remark plugins to the serialize() call
    opened by BRKalow 5
  • The matcher in middleware.ts is incompatible with presence of i18n in config

    The matcher in middleware.ts is incompatible with presence of i18n in config

    Please see this issue: https://github.com/vercel/next.js/issues/42795 (After 2 days of dealing with this, I really don't have the strength deal with this anymore.) In short, you platforms demo is utterly incompatible with the very presence of i18n in next.config.js. Once you add i18n config, the behaviour of middleware changes and the matcher is no longer valid. Index page (and only index page) starts ending on 404 and it's truly, truly pain in the ass to debug this. Especially since you expect the official example to be correct and compatible with such a basic as is internationalisation. Only when I even considered that it might be a F-up on your part I was able to solve this. I had to just throw the official matcher to the bin and handle exceptions to rewrite programatically within the middleware itself.

    (Mention or warning in the official guide would also be nice...... :))))

    opened by patrik-simunic-cz 5
  • Fix settings inputs

    Fix settings inputs

    Problem:

    I got an error caused by the inputs in /site/[id]/settings directories. Some inputs are not editable. Some inputs are also misconfigured.

    The following error is received when trying to edit. This screenshot below is taken from https://app.vercel.pub/site/[id]/settings

    image

    Solution

    • Added ref attribute to some inputs in site settings
    • Removed unused event parameter in onInput
    • Removed unused data parameter in setData

    Best regards, Ibrahim Uzun

    opened by iuzn 5
  • Add prisma relationMode for PlanetScale

    Add prisma relationMode for PlanetScale

    opened by SharadKumar 1
  • Navigating back to root of custom domain page leads to a 404.

    Navigating back to root of custom domain page leads to a 404.

    I noticed this while writing up https://github.com/vercel/platforms/issues/178, but was hoping that it'd be fixed in the final merge of https://github.com/vercel/platforms/pull/181

    If you navigate to https://demo.vercel.pub/ then click the link for "Announcing our $150M Series D" (https://demo.vercel.pub/150m-series-d), then use your browser's back button, you will get a 404.

    Here's a GIF screencast of the bug:

    CleanShot 2023-01-08 at 13 54 32

    opened by nicksergeant 1
  • Couldn't resolve dependencies related to Next@13

    Couldn't resolve dependencies related to Next@13

    Getting the source code from the master branch I'm not able to install the dependencies.

    Every time it's throwing npm ERESOLVE error:

    npm ERR! code ERESOLVE
    npm ERR! ERESOLVE could not resolve
    npm ERR! 
    npm ERR! While resolving: [email protected]
    npm ERR! Found: [email protected]
    npm ERR! node_modules/next
    npm ERR!   next@"^13.0.4" from the root project
    npm ERR!   peer next@"^12.2.5 || ^13" from [email protected]
    npm ERR!   node_modules/next-auth
    npm ERR!     next-auth@"^4.17.0" from the root project
    npm ERR!     peer next-auth@"^4.0.1" from @next-auth/[email protected]
    npm ERR!     node_modules/@next-auth/prisma-adapter
    npm ERR!       @next-auth/prisma-adapter@"^1.0.1" from the root project
    npm ERR! 
    npm ERR! Could not resolve dependency:
    npm ERR! peer next@"^11.1.0 || ^12.0.0" from [email protected]
    npm ERR! node_modules/next-plausible
    npm ERR!   next-plausible@"^3.1.4" from the root project
    npm ERR! 
    npm ERR! Conflicting peer dependency: [email protected]
    npm ERR! node_modules/next
    npm ERR!   peer next@"^11.1.0 || ^12.0.0" from [email protected]
    npm ERR!   node_modules/next-plausible
    npm ERR!     next-plausible@"^3.1.4" from the root project
    npm ERR! 
    npm ERR! Fix the upstream dependency conflict, or retry
    npm ERR! this command with --force, or --legacy-peer-deps
    npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
    npm ERR! 
    npm ERR! See /Users/user/.npm/eresolve-report.txt for a full report.
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     /Users/user/.npm/_logs/2023-01-06T18_18_32_597Z-debug-0.log
    

    I think it can be related to #159, but I'm not sure.

    Help is appreciated Thanks!

    opened by TaylorHo 8
  • Refactoring to beta app directory breaks client-side pushState navigation (prod only, works fine in dev)

    Refactoring to beta app directory breaks client-side pushState navigation (prod only, works fine in dev)

    I'm working on refactoring my multi-tenant/platform code to the new app directory and everything seems to be working fine except for client-side pushState navigation in production. Locally the client-side nav is happening via pushState, but once deployed to production, navigations result in full page loads.

    Here's a test repo: https://github.com/nicksergeant/next-13-spa-push-state-platforms

    The relevant middleware code (simplified): https://github.com/nicksergeant/next-13-spa-push-state-platforms/blob/abb3bde1213840a3f7d8d2a4ecbaf2d4c00d4e62/middleware.ts#L7-L18

    When visiting a non-middleware-caught route, pushState navigation works fine between the routes: https://next-13-spa-push-state.vercel.app/sites/foo (use the nav group Nav links to a base path of /sites/foo:)

    But when hosting on a custom domain mapping to /app/sites/foo via the middleware, the routes all still load fine but client-side pushNav is broken, so every route nav results in a full page load: https://foo.flxwebsites.com/ (use the nav group Nav links to a base path of /:)

    I tried looking through https://github.com/vercel/platforms/pull/161 to see if I'm missing some configuration change but I don't see anything...

    opened by nicksergeant 1
  • revalidate blog page failed.

    revalidate blog page failed.

    error info is reason: write EPROTO 139978634581952:error:1408F10B:SSL routines:ssl3_get_record:wrong version number.

    Does anyone know why this is? cc @steven-tey

    Some times the update will be successful, other times it will report this error

    image
    opened by EryouHao 0
  • After login not redirecting to homepage

    After login not redirecting to homepage

    I tried login in from http://app.localhost:3000/login After login (with GitHub flow)

    The page is again redirecting to http://app.localhost:3000/login

    After I log in, If I visit http://app.localhost:3000/ manually in a new tab it is redirecting properly in the browser.

    Do we need to update anything in middleware to handle this redirection?

    opened by PandiyanCool 0
Owner
Vercel
Develop. Preview. Ship. Creators of Next.js.
Vercel
Low cost, low effort P2P WebRTC serverless signalling using Cloudflare Workers

P2PCF P2PCF enables free (or cheap) serverless WebRTC signalling using a Cloudflare worker and a Cloudflare R2 bucket. The API is inspired by P2PT, bu

Greg Fodor 560 Jan 8, 2023
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
ToolJet an open-source low-code framework to build and deploy internal tools quickly without much effort from the engineering teams

ToolJet is an open-source low-code framework to build and deploy internal tools quickly without much effort from the engineering teams. You can connect to your data sources, such as databases (like PostgreSQL, MongoDB, Elasticsearch, etc), API endpoints (ToolJet supports importing OpenAPI spec & OAuth2 authorization), and external services (like Stripe, Slack, Google Sheets, Airtable) and use our pre-built UI widgets to build internal tools.

ToolJet 15.6k Jan 3, 2023
Bitloops is Low-Code Workflow Orchestration platform that helps you build backend systems and APIs 10x faster.

Bitloops Bitloops is a scalable open source Firebase substitute that can support any database and workflow orchestration. We’re building Bitloops usin

Bitloops 21 Aug 9, 2022
Brickdoc is an open-source compound document-based online workspace and low-code development platform.

Brickdoc ⚠️ Note: This software is currently under active development. Some features may be available in the future, and the API and interface may cha

Brickdoc 210 Dec 20, 2022
Brickdoc is an open-source compound document-based online workspace and low-code development platform.

Brickdoc ⚠️ Note: This software is currently under active development. Some features may be available in the future, and the API and interface may cha

MashCard 65 Jun 17, 2022
MashCard is an open-source all-in-one workspace and low-code development platform.

MashCard ⚠️ Note: This software is currently under active development. Some features may be available in the future, and the API and interface may cha

MashCard 210 Dec 20, 2022
A powerful data visualization 2D/3D large-screen editor tool with low-code.

tp-editor(2D/3D)中文说明 A topology 2D/3D editor with nodejs, express, socket.io es6, HT for Web and vite. It's a powerful large-screen data visualization

Flying Li 11 Dec 25, 2022
🛠 Solana Web3 Tools - A set of tools to improve the user experience on Web3 Solana Frontends.

?? Solana Web3 Tools - A set of tools to improve the user experience on Web3 Solana Frontends.

Holaplex 30 May 21, 2022
📄 UI clone from vercel old site (Using basic tools)

vercel old site A portfolio site, made using the latest technologies. In the construction of the site using Sass. Quality: 1) Benchmark test using a s

Pedromdsn 2 Mar 1, 2022
A crawler that crawls the site's internal links, fetching information of interest to any SEO specialist to perform appropriate analysis on the site.

Overview ?? It is a module that crawls sites and extracts basic information on any web page of interest to site owners in general, and SEO specialists

Yazan Zoghbi 2 Apr 22, 2022
A crawler that crawls the site's internal links, fetching information of interest to any SEO specialist to perform appropriate analysis on the site.

Overview ?? It is a module that crawls sites and extracts basic information on any web page of interest to site owners in general, and SEO specialists

Yazan Zoghbi 2 Apr 22, 2022
A low-feature, dependency-free and performant test runner inspired by Rust and Deno

minitest A low-feature, dependency-free and performant test runner inspired by Rust and Deno Simplicity: Use the mt test runner with the test function

Sondre Aasemoen 4 Nov 12, 2022
A fully-typed, low-level, and HyperScript-like Frontend Library 🚀

A fully-typed, low-level, and HyperScript-like Frontend Library ??

Eliaz Bobadilla 5 Apr 4, 2022
Basic Implementation of a Contract Wallet in Solidity. The owner can transfer Ether/ERC20 and execute transactions via low-level calls.

Contract Wallet Basic Implementation of a Contract Wallet in Solidity. The owner can transfer Ether/ERC20 and execute transactions via low-level calls

Junho Yeo 3 Jun 18, 2022
Modern approach to Low Quality Image Placeholders (LQIP) using webp and sharp.

lqip-modern Modern approach to Low Quality Image Placeholders (LQIP) using webp and sharp. (demo) This approach is extremely fast and produces much sm

Travis Fischer 187 Dec 30, 2022
Tooltip using only CSS and very low build size.

css-only-tooltip A very lightweight tooltip utitlity library, made using only CSS with dynamic light and dark themes. Insatallation Using npm $ npm in

Rajiv 4 Dec 11, 2022