Compare commits

...

4 Commits

Author SHA1 Message Date
Dhruwang
e3be480374 fix: prevent language switch from breaking survey orientation and resetting language on auto-save
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:22:57 +05:30
Anshuman Pandey
44d5530b48 fix: adds formbricks instance on window (#7630) 2026-04-02 07:26:48 +00:00
Matti Nannt
a314eb391e chore: add Codex environment config (#7589) 2026-04-02 07:24:02 +00:00
Matti Nannt
6c34c316d0 docs: remove non-official self-hosting options from README.md 2026-04-01 14:16:47 +02:00
6 changed files with 36 additions and 46 deletions

View File

@@ -0,0 +1,9 @@
# THIS IS AUTOGENERATED. DO NOT EDIT MANUALLY
version = 1
name = "formbricks"
[setup]
script = '''
pnpm install
pnpm dev:setup
'''

View File

@@ -127,34 +127,10 @@ Formbricks has a hosted cloud offering with a generous free plan to get you up a
Formbricks is available Open-Source under AGPLv3 license. You can host Formbricks on your own servers using Docker without a subscription.
If you opt for self-hosting Formbricks, here are a few options to consider:
#### Docker
To get started with self-hosting with Docker, take a look at our [self-hosting docs](https://formbricks.com/docs/self-hosting/deployment).
#### Community-managed One Click Hosting
##### Railway
You can deploy Formbricks on [Railway](https://railway.app) using the button below.
[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/PPDzCd)
##### RepoCloud
Or you can also deploy Formbricks on [RepoCloud](https://repocloud.io) using the button below.
[![Deploy on RepoCloud](https://d16t0pc4846x52.cloudfront.net/deploy.png)](https://repocloud.io/details/?app_id=254)
##### Zeabur
Or you can also deploy Formbricks on [Zeabur](https://zeabur.com) using the button below.
[![Deploy to Zeabur](https://zeabur.com/button.svg)](https://zeabur.com/templates/G4TUJL)
<a id="development"></a>
## 👨‍💻 Development
### Prerequisites
@@ -248,14 +224,3 @@ We currently do not offer Formbricks white-labeled. That means that we don't sel
The Enterprise Edition allows us to fund the development of Formbricks sustainably. It guarantees that the free and open-source surveying infrastructure we're building will be around for decades to come.
<a id="readme-de"></a>
## Deutsch
Formbricks ist eine freie, quelloffene und datenschutzorientierte Plattform für Surveys und Experience Management. Mit In-App-, Website-, Link- und E-Mail-Umfragen sammelt ihr Feedback entlang der gesamten User Journey.
- Website & Cloud: [formbricks.com](https://formbricks.com/) und [Cloud starten](https://app.formbricks.com/auth/signup)
- Self-Hosting: [Deployment-Dokumentation](https://formbricks.com/docs/self-hosting/deployment)
- Beitrag & Community: [Beitragen](https://formbricks.com/docs/developer-docs/contributing/get-started), [GitHub Discussions](https://github.com/formbricks/formbricks/discussions) und [Issues](https://github.com/formbricks/formbricks/issues)
- Sicherheit & Lizenz: [`SECURITY.md`](./SECURITY.md) und [AGPLv3](https://github.com/formbricks/formbricks/blob/main/LICENSE)
<p align="right"><a href="#top">🔼 Back to top</a></p>

View File

@@ -111,6 +111,13 @@ const formbricks = {
setNonce,
};
// Explicitly assign to globalThis so the wrapper SDK (@formbricks/js) can
// find us even when the UMD environment detection is fooled by a leaked
// `exports` or `module` global on the page (e.g. from another UMD bundle,
// a tag manager, or a browser extension). This runs inside the UMD factory,
// so it executes regardless of which branch the wrapper picks.
(globalThis as unknown as Record<string, unknown>).formbricks = formbricks;
type TFormbricks = typeof formbricks;
export type { TFormbricks };
export default formbricks;

View File

@@ -59,7 +59,7 @@ export function LanguageSwitch({
handleI18nLanguage(calculatedLanguageCode);
if (setDir) {
const calculateDir = isRTLLanguage(survey, calculatedLanguageCode) ? "rtl" : "auto";
const calculateDir = isRTLLanguage(survey, calculatedLanguageCode) ? "rtl" : "ltr";
setDir?.(calculateDir);
}

View File

@@ -9,12 +9,13 @@ export function RenderSurvey(props: SurveyContainerProps) {
const onFinishedTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const closeTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const isRTL = isRTLLanguage(props.survey, props.languageCode);
const [dir, setDir] = useState<"ltr" | "rtl" | "auto">(isRTL ? "rtl" : "auto");
const [dir, setDir] = useState<"ltr" | "rtl" | "auto">(isRTL ? "rtl" : "ltr");
useEffect(() => {
const isRTL = isRTLLanguage(props.survey, props.languageCode);
setDir(isRTL ? "rtl" : "auto");
}, [props.languageCode, props.survey]);
setDir(isRTL ? "rtl" : "ltr");
// eslint-disable-next-line react-hooks/exhaustive-deps -- Only recalculate direction when languageCode changes, not on survey auto-save
}, [props.languageCode]);
const close = () => {
if (onFinishedTimeoutRef.current) {

View File

@@ -1,20 +1,28 @@
import { ComponentChildren } from "preact";
import { useEffect } from "preact/hooks";
import { useEffect, useRef } from "preact/hooks";
import { I18nextProvider } from "react-i18next";
import i18n from "../../lib/i18n.config";
export const I18nProvider = ({ language, children }: { language: string; children?: ComponentChildren }) => {
const isFirstRender = useRef(true);
const prevLanguage = useRef(language);
// Set language synchronously on initial render so children get the correct translations immediately.
// This is safe because all translations are pre-loaded (bundled) in i18n.config.ts.
if (i18n.language !== language) {
i18n.changeLanguage(language);
}
// Handle language prop changes after initial render
useEffect(() => {
// On subsequent renders, skip this to avoid overriding language changes made by the user via LanguageSwitch.
if (isFirstRender.current) {
if (i18n.language !== language) {
i18n.changeLanguage(language);
}
isFirstRender.current = false;
}
// Only update language when the prop itself changes, not when i18n was changed internally by user action
useEffect(() => {
if (prevLanguage.current !== language) {
i18n.changeLanguage(language);
prevLanguage.current = language;
}
}, [language]);
// work around for react-i18next not supporting preact