Compare commits

...

2 Commits

Author SHA1 Message Date
Matti Nannt b9dcc5dd4b docs: restore Vercel reference in hubspot webhook guide
Vercel mention is about user-built webhook servers, not Formbricks
deployment — keeping it is correct.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:56:05 +02:00
Matti Nannt d7fbb439e5 chore: remove all Vercel deployment references
Formbricks no longer deploys to Vercel and does not support it for
self-hosters. This removes all Vercel-specific deployment config,
environment variables, and infrastructure references from the codebase.

- Delete vercel.json and .vercelignore
- Remove VERCEL_URL env var from env.ts, constants.ts, getPublicUrl.ts
- Remove X-Vercel-IP-Country header from v1 and v2 response API routes
- Remove VERCEL / VERCEL_URL from turbo.json build env passthrough
- Update .env.example and docker-compose.yml comments
- Update sentry.edge.config.ts comment
- Remove VERCEL_URL from license.test.ts and getPublicUrl.test.ts mocks
- Update docs to remove Vercel deployment references

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:46:40 +02:00
15 changed files with 24 additions and 73 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ SMTP_PASSWORD=smtpPassword
# S3 STORAGE #
##############
# S3 Storage is required for the file upload in serverless environments like Vercel
# S3 Storage is required for the file upload in serverless environments
S3_ACCESS_KEY=
S3_SECRET_KEY=
S3_REGION=
-1
View File
@@ -1 +0,0 @@
apps/web/.env
@@ -96,10 +96,7 @@ export const POST = withV1ApiWrapper({
const agent = new UAParser(userAgent);
const country =
requestHeaders.get("CF-IPCountry") ||
requestHeaders.get("X-Vercel-IP-Country") ||
requestHeaders.get("CloudFront-Viewer-Country") ||
undefined;
requestHeaders.get("CF-IPCountry") || requestHeaders.get("CloudFront-Viewer-Country") || undefined;
const responseInputData = responseInputValidation.data;
@@ -35,10 +35,7 @@ type TValidatedResponseInputResult =
| { response: Response };
const getCountry = (requestHeaders: Headers): string | undefined =>
requestHeaders.get("CF-IPCountry") ||
requestHeaders.get("X-Vercel-IP-Country") ||
requestHeaders.get("CloudFront-Viewer-Country") ||
undefined;
requestHeaders.get("CF-IPCountry") || requestHeaders.get("CloudFront-Viewer-Country") || undefined;
const getUnexpectedPublicErrorResponse = (): Response =>
responses.internalServerErrorResponse("Something went wrong. Please try again.", true);
+1 -2
View File
@@ -10,8 +10,7 @@ export const IS_DEVELOPMENT = env.NODE_ENV === "development";
export const E2E_TESTING = env.E2E_TESTING === "1";
// URLs
export const WEBAPP_URL =
env.WEBAPP_URL || (env.VERCEL_URL ? `https://${env.VERCEL_URL}` : false) || "http://localhost:3000";
export const WEBAPP_URL = env.WEBAPP_URL || "http://localhost:3000";
// encryption keys
export const ENCRYPTION_KEY = env.ENCRYPTION_KEY;
-2
View File
@@ -235,7 +235,6 @@ const parsedEnv = createEnv({
TURNSTILE_SITE_KEY: z.string().optional(),
RECAPTCHA_SITE_KEY: z.string().optional(),
RECAPTCHA_SECRET_KEY: z.string().optional(),
VERCEL_URL: z.string().optional(),
WEBAPP_URL: z.url().optional(),
UNSPLASH_ACCESS_KEY: z.string().optional(),
@@ -354,7 +353,6 @@ const parsedEnv = createEnv({
RECAPTCHA_SITE_KEY: process.env.RECAPTCHA_SITE_KEY,
RECAPTCHA_SECRET_KEY: process.env.RECAPTCHA_SECRET_KEY,
TERMS_URL: process.env.TERMS_URL,
VERCEL_URL: process.env.VERCEL_URL,
WEBAPP_URL: process.env.WEBAPP_URL,
UNSPLASH_ACCESS_KEY: process.env.UNSPLASH_ACCESS_KEY,
NODE_ENV: process.env.NODE_ENV,
+1 -12
View File
@@ -2,7 +2,6 @@ import { beforeEach, describe, expect, test, vi } from "vitest";
const envMock = {
WEBAPP_URL: undefined as string | undefined,
VERCEL_URL: undefined as string | undefined,
PUBLIC_URL: undefined as string | undefined,
};
@@ -19,7 +18,6 @@ const loadGetPublicDomain = async () => {
describe("getPublicDomain", () => {
beforeEach(() => {
envMock.WEBAPP_URL = undefined;
envMock.VERCEL_URL = undefined;
envMock.PUBLIC_URL = undefined;
});
@@ -31,16 +29,7 @@ describe("getPublicDomain", () => {
expect(getPublicDomain()).toBe("https://app.formbricks.com");
});
test("falls back to VERCEL_URL when WEBAPP_URL is empty", async () => {
envMock.WEBAPP_URL = " ";
envMock.VERCEL_URL = "preview.formbricks.com";
const getPublicDomain = await loadGetPublicDomain();
expect(getPublicDomain()).toBe("https://preview.formbricks.com");
});
test("falls back to localhost when WEBAPP_URL and VERCEL_URL are not set", async () => {
test("falls back to localhost when WEBAPP_URL is not set", async () => {
const getPublicDomain = await loadGetPublicDomain();
expect(getPublicDomain()).toBe("http://localhost:3000");
+1 -11
View File
@@ -2,17 +2,7 @@ import "server-only";
import { env } from "./env";
const configuredWebappUrl = env.WEBAPP_URL?.trim() ?? "";
const WEBAPP_URL = (() => {
if (configuredWebappUrl !== "") {
return configuredWebappUrl;
}
if (env.VERCEL_URL) {
return `https://${env.VERCEL_URL}`;
}
return "http://localhost:3000";
})();
const WEBAPP_URL = configuredWebappUrl !== "" ? configuredWebappUrl : "http://localhost:3000";
/**
* Returns the public domain URL
@@ -12,7 +12,7 @@ vi.mock("@/lib/env", () => ({
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -378,7 +378,7 @@ describe("License Core Logic", () => {
vi.doMock("@/lib/env", () => ({
env: {
ENTERPRISE_LICENSE_KEY: "",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -410,7 +410,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -444,7 +444,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -475,7 +475,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -506,7 +506,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -571,7 +571,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -627,7 +627,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -683,7 +683,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -722,7 +722,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -748,7 +748,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -899,7 +899,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: "test-license-key",
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -946,7 +946,7 @@ describe("License Core Logic", () => {
vi.doMock("@/lib/env", () => ({
env: {
ENTERPRISE_LICENSE_KEY: undefined,
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
@@ -969,7 +969,7 @@ describe("License Core Logic", () => {
env: {
ENTERPRISE_LICENSE_KEY: testLicenseKey,
ENVIRONMENT: "production",
VERCEL_URL: "some.vercel.url",
FORMBRICKS_COM_URL: "https://app.formbricks.com",
HTTPS_PROXY: undefined,
HTTP_PROXY: undefined,
+1 -1
View File
@@ -1,6 +1,6 @@
// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).
// The config you add here will be used whenever one of the edge features is loaded.
// Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.
// Note that this config is also required when running locally.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from "@sentry/nextjs";
import { logger } from "@formbricks/logger";
-16
View File
@@ -1,16 +0,0 @@
{
"functions": {
"app/**/*.ts": {
"maxDuration": 10,
"memory": 512
},
"app/api/cron/**/*.ts": {
"maxDuration": 180,
"memory": 512
},
"app/api/v1/client/**/*.ts": {
"maxDuration": 10,
"memory": 200
}
}
}
+1 -1
View File
@@ -87,7 +87,7 @@ x-environment: &environment
################################################### OPTIONAL (STORAGE) ###################################################
# Set S3 Storage configuration (required for the file upload in serverless environments like Vercel)
# Set S3 Storage configuration (required for the file upload in serverless environments)
# S3_ACCESS_KEY:
# S3_SECRET_KEY:
# S3_REGION:
@@ -6,7 +6,7 @@ icon: code
## TypeScript
Our codebase follows the Vercel Engineering Style Guide conventions.
Our codebase uses the `@vercel/style-guide` ESLint configurations for consistent code quality.
### ESLint Configuration
+1 -1
View File
@@ -1323,7 +1323,7 @@ Please note that their values and the logic remains exactly the same. Only the p
### Deprecated Environment Variables
- **`NEXT_PUBLIC_VERCEL_URL`**: Was used as Vercel URL (used instead of `WEBAPP_URL)`, but from v1.1, you can just set the `WEBAPP_URL` environment variable to your Vercel URL.
- **`NEXT_PUBLIC_VERCEL_URL`**: Was used as deployment URL fallback (used instead of `WEBAPP_URL`), but from v1.1, you can just set the `WEBAPP_URL` environment variable.
- **`RAILWAY_STATIC_URL`**: Was used as Railway Static URL (used instead of `WEBAPP_URL`), but from v1.1, you can just set the `WEBAPP_URL` environment variable.
-2
View File
@@ -289,8 +289,6 @@
"RECAPTCHA_SECRET_KEY",
"TELEMETRY_DISABLED",
"TERMS_URL",
"VERCEL",
"VERCEL_URL",
"VERSION",
"WEBAPP_URL",
"UNSPLASH_ACCESS_KEY",