/public/*"
+ }
+ ]
+}
+```
+
+You also need to configure CORS so that an object can be uploaded from the browser:
+
+```json
+[
+ {
+ "AllowedHeaders": ["*"],
+ "AllowedMethods": ["PUT", "POST"],
+ "AllowedOrigins": ["*"],
+ "ExposeHeaders": ["ETag"]
+ }
+]
+```
+
+### Giphy (optional)
+
+Used to search for GIF. You can create a Giphy app [here](https://developers.giphy.com/dashboard/)
+
+| Parameter | Default | Description |
+| ------------------------- | ------- | ------------- |
+| NEXT_PUBLIC_GIPHY_API_KEY | -- | Giphy API key |
+
+### Others (optional)
+
+The [official Typebot managed service](https://app.typebot.io/) uses other services such as [Stripe](https://stripe.com/) for processing payments, [Sentry](https://sentry.io/) for tracking bugs and [Sleekplan](https://sleekplan.com/) for user feedbacks.
+
+The related environment variables are listed here but you are probably not interested in these if you self-host Typebot.
+
+Stripe
+
+
+| Parameter | Default | Description |
+| ----------------------------- | ------- | --------------------- |
+| NEXT_PUBLIC_STRIPE_PUBLIC_KEY | -- | Stripe public key |
+| STRIPE_SECRET_KEY | -- | Stripe secret key |
+| STRIPE_PRICE_USD_ID | -- | Pro plan USD price id |
+| STRIPE_PRICE_EUR_ID | -- | Pro plan EUR price id |
+| STRIPE_WEBHOOK_SECRET | -- | Stripe Webhook secret |
+
+
+
+Sentry
+
+
+| Parameter | Default | Description |
+| ---------------------- | ------- | -------------------------------------- |
+| NEXT_PUBLIC_SENTRY_DSN | -- | Sentry DSN |
+| SENTRY_AUTH_TOKEN | -- | Used to upload sourcemaps on app build |
+| SENTRY_PROJECT | -- | Sentry project name |
+| SENTRY_ORG | -- | Sentry organization name |
+
+These can also be added to the `viewer` environment
+
+
+
+Vercel (custom domains)
+
+
+| Parameter | Default | Description |
+| -------------------------- | ------- | ----------------------------------------------- |
+| VERCEL_TOKEN | -- | Vercel API token |
+| VERCEL_VIEWER_PROJECT_NAME | -- | The name of the viewer project in Vercel |
+| VERCEL_TEAM_ID | -- | Vercel team ID that contains the viewer project |
+
+
+
+Sleekplan
+
+
+| Parameter | Default | Description |
+| ----------------- | ------- | ------------------------------------------------------------------------ |
+| SLEEKPLAN_SSO_KEY | -- | Sleekplan SSO key used to automatically authenticate a user in Sleekplan |
+
+
diff --git a/apps/docs/docs/self-hosting/docker.md b/apps/docs/docs/self-hosting/docker.md
new file mode 100644
index 0000000000..5053f52148
--- /dev/null
+++ b/apps/docs/docs/self-hosting/docker.md
@@ -0,0 +1,44 @@
+---
+sidebar_position: 2
+---
+
+# Docker
+
+:::note
+The easiest way to get started with Typebot is with [the official managed service in the Cloud](https://app.typebot.io). It takes 1 minute to try out the tool for free. You'll have high availability, backups, security, and maintenance all managed for you by me, Baptiste, Typebot's founder.
+
+That's also the best way to support my work, open-source software, and you'll get great service!
+:::
+
+## Requirements
+
+You need a server with Docker installed. If your server doesn't come with Docker pre-installed, you can follow [their docs](https://docs.docker.com/get-docker/) to install it.
+
+## Getting started
+
+1. Fork the repository
+
+On your server:
+
+2. Clone the forked repo:
+
+ ```sh
+ git clone https://github.com//typebot.io.git
+ ```
+
+3. Edit the `typebot-config.env` file. ([Check out the configuration guide](/self-hosting/configuration))
+
+4. Start the applications:
+
+ ```sh
+ docker-compose up -d
+ ```
+
+ It does the following:
+
+ - Create a database
+ - Run the migrations
+ - Start the builder on port 8080
+ - Start the viewer on port 8081
+
+You should see the login screen if you navigate to `http://{hostname}:8080`. Login with the `${ADMIN_EMAIL}` in order to have access to a Pro account automatically.
diff --git a/apps/docs/docs/self-hosting/get-started.md b/apps/docs/docs/self-hosting/get-started.md
new file mode 100644
index 0000000000..88bdee255f
--- /dev/null
+++ b/apps/docs/docs/self-hosting/get-started.md
@@ -0,0 +1,22 @@
+---
+sidebar_position: 1
+slug: /self-hosting
+---
+
+# Getting started
+
+:::note
+The easiest way to get started with Typebot is with [the official managed service in the Cloud](https://app.typebot.io). It takes 1 minute to try out the tool for free. You'll have high availability, backups, security, and maintenance all managed for you by me, Baptiste, Typebot's founder.
+
+That's also the best way to support my work, open-source software, and you'll get great service!
+:::
+
+Typebot is composed of 2 Next.js applications you need to deploy:
+
+- the builder, where you build your typebots
+- the viewer, where your user answer the typebot
+
+I've written guides on how to deploy Typebot using:
+
+- [Docker](/self-hosting/docker)
+- [Vercel](/self-hosting/vercel)
diff --git a/apps/docs/docs/self-hosting/overview.md b/apps/docs/docs/self-hosting/overview.md
deleted file mode 100644
index e1fc2e8d09..0000000000
--- a/apps/docs/docs/self-hosting/overview.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Self hosting
-
-:::note
-The easiest way to get started with Typebot is with [our official managed service in the Cloud](https://app.typebot.io). It takes 1 minute to create your free account. You'll have high availability, backups, security, and maintenance all managed for you by Typebot. The section below is for self-hosting Typebot on your server and managing your infrastructure.
-:::
-
-Typebot is composed of 2 Next.js applications you need to deploy:
-
-- the builder, where you build your typebots
-- the viewer, where your user answer the typebot
-
-They are connected to a Database and an S3 bucket
-
-## S3
-
-Paste this bucket policy after replacing `` with your bucket name:
-
-```json
-{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "PublicRead",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:GetObject",
- "Resource": "arn:aws:s3:::/public/*"
- }
- ]
-}
-```
-
-CORS config:
-
-```json
-[
- {
- "AllowedHeaders": ["*"],
- "AllowedMethods": ["PUT", "POST"],
- "AllowedOrigins": ["*"],
- "ExposeHeaders": ["ETag"]
- }
-]
-```
-
-```
-S3_ACCESS_KEY=minio
-S3_SECRET_KEY=minio123
-S3_BUCKET=typebot
-S3_PORT=9000
-S3_ENDPOINT=localhost
-S3_SSL=false
-```
diff --git a/apps/docs/docs/self-hosting/vercel.md b/apps/docs/docs/self-hosting/vercel.md
new file mode 100644
index 0000000000..7067d91a99
--- /dev/null
+++ b/apps/docs/docs/self-hosting/vercel.md
@@ -0,0 +1,49 @@
+---
+sidebar_position: 2
+---
+
+# Vercel
+
+:::note
+The easiest way to get started with Typebot is with [the official managed service in the Cloud](https://app.typebot.io). It takes 1 minute to try out the tool for free. You'll have high availability, backups, security, and maintenance all managed for you by me, Baptiste, Typebot's founder.
+
+That's also the best way to support my work, open-source software, and you'll get great service!
+:::
+
+## Requirements
+
+You need a PostgresDB database hosted somewhere. [Supabase](https://supabase.com/) and [Heroku](https://www.heroku.com/) offer great free options.
+
+## Getting Started
+
+Fork the repository
+
+### Deploy the builder
+
+1. Create a new Vercel project and import the forked repo
+2. Change the project name to: `typebot-builder` (or anything else)
+3. Choose Next.js framework
+4. Change the root directory to: `apps/builder`
+5. Change the build command to:
+
+ ```sh
+ cd ../.. && yarn db:migrate && yarn turbo run build --scope=builder --include-dependencies
+ ```
+
+6. Add the required environment variables ([Check out the configuration guide](/self-hosting/configuration))
+7. Hit "Deploy"
+
+### Deploy the viewer
+
+1. Create a new Vercel project and import the forked repo
+2. Change the project name to: `typebot-viewer` (or anything else)
+3. Choose Next.js framework
+4. Change the root directory to: `apps/viewer`
+5. Change the build command to:
+
+ ```sh
+ cd ../.. && yarn db:migrate && yarn turbo run build --scope=viewer --include-dependencies
+ ```
+
+6. Add the required environment variables ([Check out the configuration guide](/self-hosting/configuration))
+7. Hit "Deploy"
diff --git a/apps/docs/docusaurus.config.js b/apps/docs/docusaurus.config.js
index 6b876bc20b..a8d5f1e136 100644
--- a/apps/docs/docusaurus.config.js
+++ b/apps/docs/docusaurus.config.js
@@ -80,7 +80,8 @@ module.exports = {
],
},
colorMode: {
- disableSwitch: true,
+ disableSwitch: false,
+ respectPrefersColorScheme: true,
},
},
presets: [
diff --git a/apps/docs/src/css/custom.css b/apps/docs/src/css/custom.css
index 2be233c7c4..e46ed9e568 100644
--- a/apps/docs/src/css/custom.css
+++ b/apps/docs/src/css/custom.css
@@ -21,17 +21,6 @@ h4 {
img {
border-radius: 0.5rem;
}
-/* You can override the default Infima variables here. */
-:root {
- --ifm-color-primary: #0042da;
- --ifm-color-primary-dark: #003bc4;
- --ifm-color-primary-darker: #0038b9;
- --ifm-color-primary-darkest: #002e99;
- --ifm-color-primary-light: #0049f0;
- --ifm-color-primary-lighter: #004cfb;
- --ifm-color-primary-lightest: #1c61ff;
- --ifm-code-font-size: 95%;
-}
.docusaurus-highlight-code-line {
background-color: rgba(0, 0, 0, 0.1);
diff --git a/apps/landing-page/.env.local.example b/apps/landing-page/.env.local.example
index ea039c2934..6ff9d31af2 100644
--- a/apps/landing-page/.env.local.example
+++ b/apps/landing-page/.env.local.example
@@ -1,4 +1,4 @@
NOTION_API_TOKEN=
NOTION_DATABASE_ID=
-NEXT_PUBLIC_VIEWER_HOST=http://localhost:3001
+NEXT_PUBLIC_VIEWER_URL=http://localhost:3001
LANDING_PAGE_HOST=http://localhost:3002
\ No newline at end of file
diff --git a/apps/landing-page/next.config.js b/apps/landing-page/next.config.js
index 51200b28a2..86ccb416a1 100644
--- a/apps/landing-page/next.config.js
+++ b/apps/landing-page/next.config.js
@@ -35,7 +35,7 @@ module.exports = withBundleAnalyzer({
{
source: '/_next/static/:static*',
destination:
- process.env.NEXT_PUBLIC_VIEWER_HOST + '/_next/static/:static*',
+ process.env.NEXT_PUBLIC_VIEWER_URL + '/_next/static/:static*',
has: [
{
type: 'header',
@@ -52,11 +52,11 @@ module.exports = withBundleAnalyzer({
fallback: [
{
source: '/:typebotId*',
- destination: process.env.NEXT_PUBLIC_VIEWER_HOST + '/:typebotId*',
+ destination: process.env.NEXT_PUBLIC_VIEWER_URL + '/:typebotId*',
},
{
source: '/api/:path*',
- destination: process.env.NEXT_PUBLIC_VIEWER_HOST + '/api/:path*',
+ destination: process.env.NEXT_PUBLIC_VIEWER_URL + '/api/:path*',
},
],
}
diff --git a/apps/viewer/.env.local.example b/apps/viewer/.env.local.example
index 06c673946e..34d6e7c58d 100644
--- a/apps/viewer/.env.local.example
+++ b/apps/viewer/.env.local.example
@@ -1,16 +1,6 @@
-ENCRYPTION_SECRET=
-NEXT_PUBLIC_VIEWER_HOST=http://localhost:3001
+ENCRYPTION_SECRET=SgVkYp2s5v8y/B?E(H+MbQeThWmZq4t6 #256-bits secret (can be generated here: https://www.allkeysgenerator.com/Random/Security-Encryption-Key-Generator.aspx)
+NEXT_PUBLIC_VIEWER_URL=http://localhost:3001
DATABASE_URL=postgresql://postgres:@localhost:5432/typebot
-GOOGLE_CLIENT_ID=
-GOOGLE_CLIENT_SECRET=
-
-# (Optional) Used for email notifications
-EMAIL_NOTIFICATIONS_SERVER_USER=username
-EMAIL_NOTIFICATIONS_SERVER_PASSWORD=password
-EMAIL_NOTIFICATIONS_SERVER_HOST=smtp.example.com
-EMAIL_NOTIFICATIONS_SERVER_PORT=587
-NEXT_PUBLIC_EMAIL_NOTIFICATIONS_FROM_EMAIL=noreply@example.com
-NEXT_PUBLIC_EMAIL_NOTIFICATIONS_FROM_NAME="John Smith"
-
-NEXT_PUBLIC_SENTRY_DSN=
+# For more configuration options check out:
+https://docs.typebot.io/self-hosting/configuration
\ No newline at end of file
diff --git a/apps/viewer/libs/google-sheets.ts b/apps/viewer/libs/google-sheets.ts
index 476ad98974..34aae9be4f 100644
--- a/apps/viewer/libs/google-sheets.ts
+++ b/apps/viewer/libs/google-sheets.ts
@@ -17,7 +17,7 @@ export const getAuthenticatedGoogleClient = async (
) as GoogleSheetsCredentialsData
const oauth2Client = new OAuth2Client(
- process.env.GOOGLE_CLIENT_ID,
+ process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
`${process.env.NEXTAUTH_URL}/api/credentials/google-sheets/callback`
)
diff --git a/apps/viewer/pages/[[...publicId]].tsx b/apps/viewer/pages/[[...publicId]].tsx
index 0bdd42679c..921474329b 100644
--- a/apps/viewer/pages/[[...publicId]].tsx
+++ b/apps/viewer/pages/[[...publicId]].tsx
@@ -14,7 +14,7 @@ export const getServerSideProps: GetServerSideProps = async (
try {
if (!context.req.headers.host) return { props: {} }
typebot = context.req.headers.host.includes(
- (process.env.NEXT_PUBLIC_VIEWER_HOST ?? '').split('//')[1]
+ (process.env.NEXT_PUBLIC_VIEWER_URL ?? '').split('//')[1]
)
? await getTypebotFromPublicId(context.query.publicId?.toString())
: await getTypebotFromCustomDomain(
diff --git a/apps/viewer/pages/api/integrations/email.ts b/apps/viewer/pages/api/integrations/email.ts
index 2ce6522834..ffc25f093f 100644
--- a/apps/viewer/pages/api/integrations/email.ts
+++ b/apps/viewer/pages/api/integrations/email.ts
@@ -10,18 +10,18 @@ import { withSentry } from '@sentry/nextjs'
const cors = initMiddleware(Cors())
const defaultTransportOptions = {
- host: process.env.EMAIL_NOTIFICATIONS_SERVER_HOST,
- port: Number(process.env.EMAIL_NOTIFICATIONS_SERVER_PORT),
+ host: process.env.SMTP_HOST,
+ port: Number(process.env.SMTP_PORT),
secure: false,
auth: {
- user: process.env.EMAIL_NOTIFICATIONS_SERVER_USER,
- pass: process.env.EMAIL_NOTIFICATIONS_SERVER_PASSWORD,
+ user: process.env.SMTP_USERNAME,
+ pass: process.env.SMTP_PASSWORD,
},
}
const defaultFrom = {
- name: process.env.NEXT_PUBLIC_EMAIL_NOTIFICATIONS_FROM_NAME,
- email: process.env.NEXT_PUBLIC_EMAIL_NOTIFICATIONS_FROM_EMAIL,
+ name: process.env.NEXT_PUBLIC_SMTP_FROM?.split(' <')[0].replace(/"/g, ''),
+ email: process.env.NEXT_PUBLIC_SMTP_FROM?.match(/\<(.*)\>/)?.pop(),
}
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
diff --git a/apps/viewer/playwright.config.ts b/apps/viewer/playwright.config.ts
index 7e6280ff6e..bc1f82882b 100644
--- a/apps/viewer/playwright.config.ts
+++ b/apps/viewer/playwright.config.ts
@@ -17,7 +17,7 @@ const config: PlaywrightTestConfig = {
maxFailures: process.env.CI ? 10 : undefined,
use: {
actionTimeout: 0,
- baseURL: process.env.NEXT_PUBLIC_VIEWER_HOST,
+ baseURL: process.env.NEXT_PUBLIC_VIEWER_URL,
storageState: path.join(__dirname, 'playwright/proUser.json'),
trace: 'on-first-retry',
video: 'retain-on-failure',
diff --git a/packages/bot-engine/src/components/TypebotViewer.tsx b/packages/bot-engine/src/components/TypebotViewer.tsx
index 10b892a6d5..6a95eaaeb7 100644
--- a/packages/bot-engine/src/components/TypebotViewer.tsx
+++ b/packages/bot-engine/src/components/TypebotViewer.tsx
@@ -33,7 +33,7 @@ export type TypebotViewerProps = {
}
export const TypebotViewer = ({
typebot,
- apiHost = process.env.NEXT_PUBLIC_VIEWER_HOST,
+ apiHost = process.env.NEXT_PUBLIC_VIEWER_URL,
isPreview = false,
onNewLog,
onNewBlockVisible,
@@ -59,7 +59,7 @@ export const TypebotViewer = ({
const handleCompleted = () => onCompleted && onCompleted()
if (!apiHost)
- return process.env.NEXT_PUBLIC_VIEWER_HOST is missing in env
+ return process.env.NEXT_PUBLIC_VIEWER_URL is missing in env
return (