diff --git a/apps/docs/components/JwtGenerator.js b/apps/docs/components/JwtGenerator.js
new file mode 100644
index 00000000000..46dd4758e31
--- /dev/null
+++ b/apps/docs/components/JwtGenerator.js
@@ -0,0 +1,96 @@
+import React, { useState } from 'react'
+import KJUR from 'jsrsasign'
+import CodeBlock from './CodeBlock/CodeBlock'
+import { Button } from 'ui'
+
+const JWT_HEADER = { alg: 'HS256', typ: 'JWT' }
+const now = new Date()
+const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
+const fiveYears = new Date(now.getFullYear() + 5, now.getMonth(), now.getDate())
+const anonToken = `
+{
+ "role": "anon",
+ "iss": "supabase",
+ "iat": ${Math.floor(today / 1000)},
+ "exp": ${Math.floor(fiveYears / 1000)}
+}
+`.trim()
+
+const serviceToken = `
+{
+ "role": "service_role",
+ "iss": "supabase",
+ "iat": ${Math.floor(today / 1000)},
+ "exp": ${Math.floor(fiveYears / 1000)}
+}
+`.trim()
+
+export default function JwtGenerator({}) {
+ const secret = [...Array(40)].map(() => Math.random().toString(36)[2]).join('')
+
+ const [jwtSecret, setJwtSecret] = useState(secret)
+ const [token, setToken] = useState(anonToken)
+ const [signedToken, setSignedToken] = useState('')
+
+ const handleKeySelection = (e) => {
+ const val = e.target.value
+ if (val == 'service') setToken(serviceToken)
+ else setToken(anonToken)
+ }
+ const generate = () => {
+ const signedJWT = KJUR.jws.JWS.sign(null, JWT_HEADER, token, jwtSecret)
+ setSignedToken(signedJWT)
+ }
+
+ return (
+
+
+
+ setJwtSecret(e.target.value)}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+ {signedToken && (
+
+
Generated Token:
+
+ {signedToken}
+
+
+ )}
+
+ )
+}
diff --git a/apps/docs/components/index.tsx b/apps/docs/components/index.tsx
index f97096022d1..56e0b9b3b2d 100644
--- a/apps/docs/components/index.tsx
+++ b/apps/docs/components/index.tsx
@@ -1,10 +1,11 @@
-import { Tabs, Alert } from 'ui'
+import { Button, Tabs, Alert } from 'ui'
// Common components
import Admonition from './Admonition'
import ButtonCard from './ButtonCard'
import CodeBlock from './CodeBlock/CodeBlock'
import { parseNumericRange } from './CodeBlock/CodeBlock.utils'
+import JwtGenerator from './JwtGenerator'
// Page specific components
import Frameworks from './Frameworks'
@@ -18,11 +19,13 @@ import ProjectSetup from './MDX/project_setup.mdx'
const components = {
Admonition,
+ Button,
ButtonCard,
CodeBlock,
Frameworks,
AuthProviders,
FunctionsExamples,
+ JwtGenerator,
QuickstartIntro,
ProjectSetup,
Alert: (props: any) => (
diff --git a/apps/docs/docs/guides/hosting/overview.mdx b/apps/docs/docs/guides/hosting/overview.mdx
index 368ba3ce8b1..00c9a6b9b14 100644
--- a/apps/docs/docs/guides/hosting/overview.mdx
+++ b/apps/docs/docs/guides/hosting/overview.mdx
@@ -5,8 +5,6 @@ sidebar_label: Overview
description: Getting started with Self Hosting.
---
-import JwtGenerator from '@site/src/components/JwtGenerator'
-
There are several ways to use Supabase:
- [Supabase Cloud](https://app.supabase.com): you don't need to deploy anything. We will manage and scale your infrastructure.