Compare commits

...

180 Commits

Author SHA1 Message Date
Shubham Palriwala
6e2fa40155 feat: 99 unlimited plan (#2137) 2024-02-27 13:10:39 +00:00
Piyush Gupta
df2cb9e26c feat: add picture selection support to response filters (#2105) 2024-02-27 13:06:31 +00:00
Nathan Clevenger
e33d640620 fix: landing page typo (#2135) 2024-02-27 12:58:25 +00:00
Matti Nannt
32dcb75ef8 fix: health endpoint s3 connection (#2136) 2024-02-27 13:20:49 +01:00
Midka
b1c2f90feb fix(S3): add support for custom endpoint (#2049)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-02-27 11:39:43 +00:00
Dhruwang Jariwala
8064e1ecf6 fix: Check for complete submission before displaying CTA on Thank You… (#1979)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-27 11:35:52 +00:00
Shubham Palriwala
21787f2af5 fix: react console errors & warnings in dashboard & survey editor (#2113)
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-02-27 11:06:01 +00:00
Sebastian Goscinski
5acdf018d3 feat: custom S3 endpoint to use third party storage services (#2133)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-27 10:53:00 +00:00
Matti Nannt
47ec19b46d chore: update version for 1.6 release (#2123) 2024-02-26 22:31:52 +01:00
Dhruwang Jariwala
60b474a4f9 fix: unformatted recall question in logic editor (#2126) 2024-02-26 20:17:59 +00:00
Dhruwang Jariwala
a027d1ef3d fix: gs readability issue for multiple file uploads (#2127) 2024-02-26 20:07:42 +00:00
Dhruwang Jariwala
7f68b4f800 fix: welcome card fixes (#2128) 2024-02-26 20:06:22 +00:00
Matti Nannt
71717c6b02 fix: github action (#2131) 2024-02-26 19:29:28 +00:00
Michele
8ad1ecfcb9 feat: added Tiledesk to OSS friends (#2124) 2024-02-26 07:37:19 +00:00
Matti Nannt
338b21620b chore: Add database migration dockerfile (#2122) 2024-02-24 16:08:57 +00:00
Matti Nannt
78ed91b7c3 chore: update dockerfile to use turbo prune (#2121) 2024-02-24 15:39:46 +00:00
Matti Nannt
dbe249e6ce chore: run github actions with node 20 (#2120) 2024-02-24 11:07:46 +00:00
Shubham Palriwala
241716b4f3 docs: add migration guide for v1.6 (#2010)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-23 16:41:38 +00:00
Anshuman Pandey
f19e1960b7 fix: adds relative image url path for self hosters without s3 (#2096) 2024-02-23 14:50:08 +00:00
Anshuman Pandey
70b7f6614e feat: on the fly triggers (#2110)
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-23 14:37:35 +00:00
Johannes
a680a62220 fix: adjust name size in survey card (#2118) 2024-02-23 13:37:41 +00:00
Piyush Gupta
cb17e185f1 fix: hide attributes from sync endpoint (#2117)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-23 12:14:10 +00:00
Johannes
8b2990a16f fix: remove delete functionality from handle Go Back in survey editor (#2107)
Co-authored-by: Shubham Palriwala <spalriwalau@gmail.com>
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-02-23 10:26:32 +00:00
Anshuman Pandey
6111e02b1b fix: edit segment card changes (#2081) 2024-02-23 10:16:22 +00:00
Matti Nannt
186feefdb5 chore: caching optimisations in sync endpoints (#2111)
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-02-22 18:18:06 +00:00
Shubham Palriwala
312858e278 fix: dont interrupt response on display updation failure (#2102)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-02-22 14:45:30 +00:00
Jonas Höbenreich
61ca42eb83 feat: add Cache-Control header to public file serving (#2099) 2024-02-22 14:36:19 +00:00
Shubham Palriwala
7f21e65625 feat: custom OIDC providers (#2109) 2024-02-22 14:31:48 +00:00
Dhruwang Jariwala
cdf8e91dad fix: Rating issue fix (#2100)
Co-authored-by: Johannes <johannes@formbricks.com>
2024-02-22 10:45:49 +00:00
Johannes
aa55ced425 feat: allow remove branding of in app surveys (#2085)
Co-authored-by: Dhruwang <dhruwangjariwala18@gmail.com>
2024-02-22 10:13:34 +00:00
Shubham Palriwala
1d2c8719c3 fix: google oauth check only on google envs (#2106) 2024-02-22 09:09:23 +00:00
Piyush Gupta
09ede38509 feat: move download functionality server side (#2103)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-22 08:44:57 +00:00
Johannes
be14678cd0 fix: show real date and remember survey list orientation (#2108) 2024-02-21 15:25:19 +00:00
Piyush Gupta
d2e6238ad7 feat: move response filtering server-side (#1844)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-20 15:34:34 +00:00
Shubham Palriwala
f69e8e82e3 fix: rewrite stripe + bug in unsubscribing (#2084) 2024-02-20 07:49:53 +00:00
Johannes
96808b3464 chore: add themeisle and optimole logos to lp (#2086)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-02-19 12:39:37 +00:00
Johannes
3ce4e7f7a2 chore: added enterprise license page for self-hosters incl. status indicator (#2077)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-19 12:29:43 +00:00
Shubham Palriwala
606ca4ea98 docs: link-surveys: hidden fields page (#2082)
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-02-19 11:20:29 +00:00
Shubham Palriwala
acf279d3ba feat: add RATE_LIMITING_DISABLED env var to bypass rate limiting (#2091)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-19 10:58:35 +00:00
Shubham Palriwala
2425dc5459 feat: rate limit per user per env sync user identification endpoint (#2090)
Co-authored-by: review-agent-prime[bot] <147289438+review-agent-prime[bot]@users.noreply.github.com>
2024-02-19 10:58:30 +00:00
Shubham Palriwala
6ae782b984 feat: downgrade team functionality when payment subscription has expired (#2092) 2024-02-19 10:50:24 +00:00
Sudhanshu Pandey
eadf63b47e chore: revert ECS Github Action (#2094) 2024-02-19 10:32:53 +00:00
Shubham Palriwala
12e5f097a5 docs: move env vars to config page (#2095)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-19 10:29:37 +00:00
Jonas Höbenreich
4c1e688f12 feat: add caching to survey sync (#2011) 2024-02-16 08:38:01 +00:00
Shubham Palriwala
3b2cf7c0da fix: (landing page) setup code font visibility (#2079)
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-02-15 17:50:50 +00:00
Shubham Palriwala
4cc3ee278d feat: add go to dashboard button in error modal (#2063) 2024-02-15 17:45:10 +00:00
Malte Hecht
95493608ed fix: Add missing space to .env.example (#2075) 2024-02-15 17:44:40 +00:00
Johannes
101a029344 chore: Add new logos to readme (#2087) 2024-02-15 15:39:06 +00:00
Shubham Palriwala
92fe0adf1e fix: (docs) dark mode hover states (#2080) 2024-02-15 13:47:37 +00:00
Matti Nannt
0e41ebf849 chore: reduce vercel memory usage (#2083) 2024-02-15 11:55:47 +00:00
Matti Nannt
969fb0241a fix: formbricks-com build error (#2072) 2024-02-14 13:25:27 +00:00
McPizza
d588a61be5 docs: add UnInbox to OSS Friends (#2076) 2024-02-14 12:54:10 +00:00
Dhruwang Jariwala
82207d8f52 fix: redirect for nested windows (#2074) 2024-02-14 12:41:42 +00:00
Anshuman Pandey
c85ae57697 fix: image cache revalidation (#2071)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-02-14 10:32:44 +00:00
Anshuman Pandey
e6fe027e57 fix: segments modals (#2070) 2024-02-14 09:41:57 +00:00
Nick van Leeuwen
3090151c50 feat: Added the ability to remove the login via email button (#1993)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-14 09:02:08 +00:00
Sudhanshu Pandey
f899cb0478 fix: ECS Github Action (#2069) 2024-02-14 07:51:39 +00:00
Sudhanshu Pandey
f5c5ce23b0 fix: ecs Github Action (#2066) 2024-02-13 15:56:45 +00:00
Johannes
084b17e950 fix: lp fixes and updates (#2067) 2024-02-13 15:13:30 +00:00
Johannes
a643d90a2b chore: Add StackedCardsContainer component (#2064) 2024-02-13 15:06:19 +00:00
Anshuman Pandey
10b61be19a fix: load segment modal UI fix (#2065) 2024-02-13 11:04:29 +00:00
Sudhanshu Pandey
f0833786d9 fix: ECS deployment GitHub Action (#2061)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-02-13 07:56:01 +00:00
Anshuman Pandey
ad9296a00c fix: getSyncSurveys (#2062) 2024-02-13 06:44:46 +00:00
Anshuman Pandey
bf51e578b2 feat: Advanced Targeting (#758)
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-12 19:08:47 +00:00
meletj
000a11c8bc docs: add Prisma to OSS Friends (#2059) 2024-02-12 16:12:31 +00:00
Jonas Höbenreich
531facd74c feat: add debug mode via url parameter (#2039)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-02-12 13:00:20 +00:00
Johannes
7843e2da99 fix: update Upgrade Notifier in branding removal (#2058) 2024-02-12 11:51:52 +00:00
Dhruwang Jariwala
77e2472175 chore: redirect for deletion survey (#2054)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-12 10:56:16 +00:00
Dhruwang Jariwala
336480a338 fix: cache revalidation on createResponse and docs (#2057) 2024-02-12 10:53:59 +00:00
Dhruwang Jariwala
f102901b90 fix: open text question validation issue (#2051)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-12 10:48:46 +00:00
Shubham Palriwala
14b162aabc feat: group events by environmentId in posthog (#2036)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-12 10:11:05 +00:00
Dhruwang Jariwala
07f28d0971 fix: team issues (#2050)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-12 09:53:38 +00:00
Dhruwang Jariwala
40d3ac19d1 chore: "include one of" option for single select (#2052) 2024-02-12 08:31:58 +00:00
Dhruwang Jariwala
7c0a9bed46 fix: multi select scroll issue (#2053) 2024-02-12 08:25:32 +00:00
Dhruwang Jariwala
c372108b91 fix: weekly template (#2041) 2024-02-09 05:42:40 +00:00
Dhruwang Jariwala
0bccee23e9 fix: File upload issues and tweaks (#2040)
Co-authored-by: Johannes <johannes@formbricks.com>
2024-02-08 15:41:00 +00:00
Dhruwang Jariwala
831bf148d8 fix: bg animation and publish survey issue (#2037)
Co-authored-by: Johannes <johannes@formbricks.com>
2024-02-08 14:18:17 +00:00
Shubham Palriwala
4b1bbf0ba4 feat: double client side api rate limits (#2043) 2024-02-08 14:16:51 +00:00
Matti Nannt
5ef9b574ab docs: fix env variable table (#2035) 2024-02-07 18:01:13 +00:00
Matti Nannt
d55611ce02 chore: fix formbricks-com build issues (#2033) 2024-02-07 13:44:14 +00:00
Thomas Kaul
07228c4575 docs: Update README.md (#2032)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-07 13:42:28 +00:00
Shubham Palriwala
7bd15053e5 docs: mention reverse proxy & fix font shade in dark mode (#2031)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-07 12:10:48 +00:00
Matti Nannt
548251a2ba chore: remove *_auth_enabled env variables (#1997) 2024-02-07 11:35:13 +00:00
Matti Nannt
fd6322652b docs: add more license information (#2030) 2024-02-07 11:24:15 +00:00
Johannes
8b1718c9b3 chore: tweak billing page for clarity (#2028) 2024-02-07 09:10:34 +00:00
Shubham Palriwala
82aba726db docs: readme for @formbricks/api (#2027) 2024-02-07 08:15:36 +00:00
Dhruwang Jariwala
b264b2473b fix: gs spreadsheet scroll issue (#2020) 2024-02-07 07:45:47 +00:00
Matti Nannt
e80d71e654 fix: posthog free limit reporting (#2026) 2024-02-06 20:40:00 +00:00
Jonas Höbenreich
3472033c7e feat: Introduce Dynamic Pixel Server for Seamless Self-Hosting (#2015)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-06 16:10:49 +00:00
Matti Nannt
3db4f59b0a chore: update formbricks pricing page with new features (#2025) 2024-02-06 11:26:38 +00:00
Johannes
5c023d58d9 chore: tidy up blog and article typos (#2023) 2024-02-06 10:21:17 +00:00
Shubham Palriwala
6a9968bd97 feat: send free limit reached to PostHog (#2014)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-02-06 09:55:09 +00:00
Matti Nannt
9c90c9faf1 fix: deleted responses still show in API (#2022) 2024-02-06 09:37:05 +00:00
Shubham Palriwala
b51e9ccdb9 fix: remove default env vars in docker compose (#2018) 2024-02-05 16:09:05 +00:00
Shubham Palriwala
967680263b feat: cache web builds & playwright binaries in CI (#2009) 2024-02-05 11:19:11 +00:00
Matti Nannt
8a4bbfbd1c chore: prepare 1.5.1 release (#2012) 2024-02-05 09:56:21 +00:00
Rotimi Best
9f63822038 docs: add ClassroomIO to OSS Friends (#2008) 2024-02-05 07:53:54 +00:00
Jonas Höbenreich
9756aed94f feat: Add support for Cloudfront country header (#2003) 2024-02-04 11:31:34 +00:00
Matti Nannt
97562118a1 fix: create survey API expects creator (#2007) 2024-02-04 09:03:38 +00:00
Sudhanshu Pandey
fd217308e1 fix: ECS deployment GitHub Action (#2005) 2024-02-02 19:26:00 +00:00
Matti Nannt
6d4098b8b8 chore: remove old CLA form from docs & github templates (#1995) 2024-02-02 09:09:58 +00:00
Sudhanshu Pandey
2f7b70516c fix: ecs github action (#1992) 2024-02-02 08:58:14 +00:00
Shubham Palriwala
9761483530 feat: auto subscribing to teams survey responses email (#1990)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-01 17:20:54 +00:00
Matti Nannt
6cea8a2246 fix: formbricks-com build errors (#1991) 2024-02-01 10:08:25 +00:00
Dhruwang Jariwala
b7250a284a fix: default autocomplete value (#1986)
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-01 09:30:17 +00:00
Dhruwang Jariwala
1402f4a48b chore: Tweaked survey list (#1978)
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-02-01 07:51:21 +00:00
Shubham Palriwala
70fe0fb7a7 feat: enable weekly summary & support for callbacks on login (#1885)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-02-01 06:16:21 +00:00
Sudhanshu Pandey
5471324cfe fix: ecs-deployment.yml (#1989) 2024-01-31 20:45:40 +00:00
Sudhanshu Pandey
0a78848612 fix: ECS deployment Github Action (#1988) 2024-01-31 19:39:40 +00:00
Dhruwang Jariwala
f553bce7f1 fix: links and survey overlapping (#1985)
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-01-31 15:53:51 +00:00
Dhruwang Jariwala
43566a54b6 fix: Phone validation (#1987) 2024-01-31 14:21:16 +00:00
Matti Nannt
51a811ac8e fix: app page redirect throws error (#1984) 2024-01-31 10:59:17 +00:00
Sudhanshu Pandey
74fba30d5f feat(github action): Add's a new GitHub Action to deploy webapp to ECS cluster (#1982)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-01-31 10:57:25 +00:00
Shubham Palriwala
22ea797b15 feat: (docs) quickstart for link surveys (#1981)
Co-authored-by: Johannes <johannes@formbricks.com>
2024-01-30 20:52:31 +00:00
Johannes
0ce10e8824 docs: Add newsletter survey to best practices (#1980)
Co-authored-by: Olasunkanmi Balogun <olasunkanmiibalogun@gmail.com>
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-01-30 15:41:27 +00:00
Matti Nannt
ca0d63a0fc chore: remove getting started email (#1977) 2024-01-30 11:52:14 +00:00
Matti Nannt
2a9b34104d feat: add support for customer-io formbricks users sync (#1976) 2024-01-30 11:08:40 +00:00
Shubham Palriwala
16cbc3365b feat: custom placeholder label for other option in single & multi select (#1971)
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-01-30 09:21:01 +00:00
Olasunkanmi Balogun
0122ccb797 chore: Newsletter article and best practices docs bug fix (#1952)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
Co-authored-by: Johannes <johannes@formbricks.com>
2024-01-30 09:12:41 +00:00
Dhruwang Jariwala
fc2beb3d19 chore: Tags and notes to csv exports (#1968)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-01-29 14:35:40 +00:00
Dhruwang Jariwala
698da4c3a1 feat: Randomizer for in-app surveys (#1972)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-01-29 12:54:32 +00:00
Dhruwang Jariwala
07f6f1d04b fix: stars issue in rating question (#1973) 2024-01-29 07:49:29 +00:00
Dhruwang Jariwala
6dcd06534b fix: single use survey not working with email verification (#1935)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-01-26 16:31:18 +00:00
Guilherme Oenning
1fb165e5ad docs: add Aptabase to OSS friends (#1969)
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-01-26 15:02:49 +00:00
Dhruwang Jariwala
3775b3e142 fix: thank you card tweaks (#1956)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-01-26 14:19:03 +00:00
Dhruwang Jariwala
92417d4d97 chore: Added average to rating summary (#1966)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-01-26 14:18:10 +00:00
Matti Nannt
6340d499b9 chore: prepare 1.5.0 release, update deps (#1962) 2024-01-26 10:28:36 +00:00
Johannes
4dfe1d9af0 chore: tweak sharing results UX (#1964) 2024-01-26 10:02:15 +00:00
Anshuman Pandey
ee5a519120 feat: lazy loading for @formbricks/surveys (#1940)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
Co-authored-by: ShubhamPalriwala <spalriwalau@gmail.com>
2024-01-25 15:05:46 +00:00
Dhruwang Jariwala
c29c580fbe fix: Response card issues (#1957)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-01-25 11:55:52 +00:00
Anshuman Pandey
48cf9de000 fix: e2e flakyness (#1961) 2024-01-25 09:36:03 +00:00
Shubham Palriwala
1945b6ddf5 feat: (docs) introducing in-app surveys section (#1942)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-01-24 13:16:27 +00:00
Shubham Palriwala
f8d4c45631 fix: only consider subscriptions if they are in active state (#1955) 2024-01-24 12:42:07 +00:00
Anshuman Pandey
d8bd42297f fix: management storage api (#1958) 2024-01-24 12:24:09 +00:00
Dhruwang Jariwala
f386de1bd7 fix: template breaking issue (#1954) 2024-01-24 07:17:47 +00:00
Johannes
cc8669c886 fix: typo in email (#1953) 2024-01-24 00:02:33 +00:00
Johannes
3d6e9740aa chore: update and tweak community page (#1950) 2024-01-23 21:11:50 +00:00
Johannes
6ea7486bb1 fix: members table UI, tweak upsell UI (#1949) 2024-01-23 20:09:30 +00:00
Johannes
2f17c87a80 chore: add c.io to privacy policy (#1948) 2024-01-23 18:11:46 +00:00
Olasunkanmi Balogun
6ac60a9858 chore: add waitlist survey to the blog (#1944)
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-01-23 17:50:52 +00:00
Sushant
78c2cf451b feat: Create new team (#1925)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-01-23 17:38:19 +00:00
Dhruwang Jariwala
64db29417d chore: added DOMPurify to prevent xss (#1894)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-01-23 17:05:47 +00:00
Dhruwang Jariwala
aa63c89a6a fix: Tweaked thank you card (#1923)
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-01-23 15:26:16 +00:00
Dhruwang Jariwala
1fd339e5a0 chore: Adds verified email to response data for email verification surveys (#1943) 2024-01-23 09:26:14 +00:00
Shubham Palriwala
8ebbad4314 feat: (docs) blog article on self hosting session (#1941) 2024-01-23 09:03:54 +00:00
Anshuman Pandey
f1535d3993 feat: e2e test for actions (#1831)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-01-23 06:47:44 +00:00
Olasunkanmi Balogun
cad32d19e9 chore: Add best website feedback tools 2024 article to the blog (#1912)
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-01-22 20:24:00 +00:00
Shubham Palriwala
64ddcb64b7 feat: send getting started email on signup (#1877)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
2024-01-22 20:20:01 +00:00
Johannes
5ab55bb2b3 fix: remove ossgg folder (#1939) 2024-01-22 19:45:38 +00:00
tyjkerr
2c008d544c feat: survey error modal/page (#1140)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
Co-authored-by: Dhruwang <dhruwangjariwala18@gmail.com>
2024-01-22 15:38:23 +00:00
Anshuman Pandey
59bb977b3b fix: error wrapper (#1937) 2024-01-22 12:52:25 +00:00
Anshuman Pandey
64ff49acf3 fix: error handling for file upload (#1936) 2024-01-22 12:48:45 +00:00
Shubham Palriwala
69293e2d1a chore: upgrade formbricks-com to latest deps (#1866)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-01-22 10:49:33 +00:00
Ryan Martin
7111480820 docs: typos & broken markdown formatting (#1924)
Co-authored-by: Ryan Martin <rmrt1n@users.noreply.github.com>
2024-01-22 10:10:25 +00:00
dependabot[bot]
55f4ff6fee chore(deps-dev): bump vite from 5.0.11 to 5.0.12 (#1929)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-22 09:43:48 +00:00
Dhruwang Jariwala
e3056ed403 fix: Improved UX for survey background selection (#1931) 2024-01-22 09:40:16 +00:00
Shubham Palriwala
7059d3843d feat: logs command in prod script (#1934) 2024-01-22 09:17:06 +00:00
Dhruwang Jariwala
c89d030222 feat: report survey link (#1932) 2024-01-22 09:11:06 +00:00
Dhruwang Jariwala
6a76330c84 fix: response card tweaks (#1933) 2024-01-22 09:02:18 +00:00
Shubham Palriwala
bd256b9426 feat: /health endpoint (#1898)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-01-22 07:48:42 +00:00
Johannes
c4ace07765 fix: tweak sharing results UX (#1928) 2024-01-19 19:09:55 +00:00
Dhruwang Jariwala
8745fd8b92 fix: empty logic editor issue (#1915) 2024-01-18 10:24:02 +00:00
Dhruwang Jariwala
2baa9a0108 fix: zindex issue and fallback input issue in recall (#1919) 2024-01-18 10:22:52 +00:00
Dhruwang Jariwala
f91a7b2c7a fix: duplicate image issue (#1920) 2024-01-18 10:21:38 +00:00
Dhruwang Jariwala
542e4da878 fix: full width image issue on welcome card (#1921) 2024-01-18 10:20:29 +00:00
Dhruwang Jariwala
41aa82814d fix: logic jump for other option (#1922) 2024-01-18 10:19:48 +00:00
Johannes
998773be6b fix: Add response api link to docs navbar (#1918) 2024-01-17 21:40:58 +00:00
Johannes
f35b007e98 fix: Tweak survey settings tab and share modal to shorten viral loop (#1882)
Co-authored-by: Dhruwang <dhruwangjariwala18@gmail.com>
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
Co-authored-by: ShubhamPalriwala <spalriwalau@gmail.com>
2024-01-17 14:29:16 +00:00
Dhruwang Jariwala
f2800632e3 feat: Recall functionality (#1789)
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-01-17 13:35:02 +00:00
Dhruwang Jariwala
e30f16cec2 fix: Embed in an Email preview (#1913)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2024-01-17 11:09:44 +00:00
Matti Nannt
3586818fda fix: update stripe usage report times to fix conflicts (#1914) 2024-01-17 10:59:04 +00:00
Khanh Ho
602238f6a5 feat: Add "How to add people" to People View (#1910) 2024-01-17 10:23:46 +00:00
Johannes
1901313873 docs: add self-hosting license form (#1911) 2024-01-17 10:07:49 +00:00
Shubham Palriwala
8652eb69de feat: integrate depot.dev for faster docker arm builds (#1907) 2024-01-17 07:14:51 +00:00
Shubham Palriwala
e896a737f4 feat: increase rate limit for client api endpoints (#1904) 2024-01-17 07:11:47 +00:00
Shubham Palriwala
4f61b4320f fix: email handling & e2e CI bug (#1896) 2024-01-17 06:40:49 +00:00
Shubham Palriwala
9d1cb8f595 fix: (docs) mention google drive api for sheets integration in self host (#1905) 2024-01-16 12:50:24 +00:00
Dhruwang Jariwala
81e9ac0e12 fix: next button tweak (#1903) 2024-01-16 09:34:44 +00:00
Shubham Palriwala
be4534da2d fix: formbricks docs survey endpoint (#1901) 2024-01-16 07:14:58 +00:00
Shubham Palriwala
f4a31ad563 feat: unit tests for survey service (#1813)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
2024-01-16 05:41:16 +00:00
663 changed files with 28840 additions and 13489 deletions

View File

@@ -1,8 +0,0 @@
# Changesets
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

View File

@@ -1,7 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
**/node_modules
# **/node_modules
.pnp
.pnp.js
.pnpm-store/

View File

@@ -1,8 +1,7 @@
########################################################################
# ------------ MANDATORY (CHANGE ACCORDING TO YOUR SETUP) ------------#
# ------------ MANDATORY (CHANGE ACCORDING TO YOUR SETUP) ------------ #
########################################################################
############
# BASICS #
############
@@ -51,13 +50,25 @@ SMTP_SECURE_ENABLED=0
SMTP_USER=smtpUser
SMTP_PASSWORD=smtpPassword
########################################################################
# ------------------------------ OPTIONAL -----------------------------#
########################################################################
# Uncomment the variables you would like to use and customize the values.
##############
# S3 STORAGE #
##############
# S3 Storage is required for the file uplaod in serverless environments like Vercel
S3_ACCESS_KEY=
S3_SECRET_KEY=
S3_REGION=
S3_BUCKET_NAME=
# Configure a third party S3 compatible storage service endpoint like StorJ leave empty if you use Amazon S3
# e.g., https://gateway.storjshare.io
S3_ENDPOINT_URL=
#####################
# Disable Features #
#####################
@@ -71,6 +82,9 @@ PASSWORD_RESET_DISABLED=1
# Signup. Disable the ability for new users to create an account.
# SIGNUP_DISABLED=1
# Email login. Disable the ability for users to login with email.
# EMAIL_AUTH_DISABLED=1
# Team Invite. Disable the ability for invited users to create an account.
# INVITE_DISABLED=1
@@ -84,21 +98,25 @@ TERMS_URL=
IMPRINT_URL=
# Configure Github Login
GITHUB_AUTH_ENABLED=0
GITHUB_ID=
GITHUB_SECRET=
# Configure Google Login
GOOGLE_AUTH_ENABLED=0
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
# Configure Azure Active Directory Login
AZUREAD_AUTH_ENABLED=0
AZUREAD_CLIENT_ID=
AZUREAD_CLIENT_SECRET=
AZUREAD_TENANT_ID=
# OpenID Connect (OIDC) configuration
# OIDC_CLIENT_ID=
# OIDC_CLIENT_SECRET=
# OIDC_ISSUER=
# OIDC_DISPLAY_NAME=
# OIDC_SIGNING_ALGORITHM=
# Cron Secret
CRON_SECRET=
@@ -118,12 +136,12 @@ NEXT_PUBLIC_FORMBRICKS_API_HOST=
NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID=
NEXT_PUBLIC_FORMBRICKS_ONBOARDING_SURVEY_ID=
# Oauth credentials for Google sheet integration
# Oauth credentials for Google sheet integration
GOOGLE_SHEETS_CLIENT_ID=
GOOGLE_SHEETS_CLIENT_SECRET=
GOOGLE_SHEETS_REDIRECT_URL=
# Oauth credentials for Airtable integration
# Oauth credentials for Airtable integration
AIRTABLE_CLIENT_ID=
# Enterprise License Key
@@ -137,3 +155,10 @@ ENTERPRISE_LICENSE_KEY=
# set to 1 to skip onboarding for new users
# ONBOARDING_DISABLED=1
# Send new users to customer.io
# CUSTOMER_IO_API_KEY=
# CUSTOMER_IO_SITE_ID=
# Ignore Rate Limiting across the Formbricks app
# RATE_LIMITING_DISABLED=1

View File

@@ -42,7 +42,6 @@ body:
- First time: Please read our [introductory blog post](https://formbricks.com/blog/join-the-formtribe)
- All UI components are in the package `formbricks/ui`
- Run `pnpm go` to find a demo app to test in-app surveys at `localhost:3002`
- Everything is type-safe
- We use **chatGPT** to help refactor code. Use our [Formbricks ✨ megaprompt ✨](https://github.com/formbricks/formbricks/blob/main/megaprompt.md) to create the right
context before you write your prompt.
- Everything is type-safe.
- We use **chatGPT** to help refactor code.
- Anything unclear? [Ask in Discord](https://formbricks.com/discord)

View File

@@ -32,7 +32,6 @@ Fixes # (issue)
- [ ] Removed all `console.logs`
- [ ] Merged the latest changes from main onto my branch with `git pull origin main`
- [ ] My changes don't cause any responsiveness issues
- [ ] First PR at Formbricks? [Please sign the CLA!](https://formbricks.com/clmyhzfrymr4ko00hycsg1tvx) Without it we wont be able to merge it 🙏
### Appreciated

View File

@@ -0,0 +1,53 @@
name: Build & Cache Web App
runs:
using: "composite"
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Cache Build
uses: actions/cache@v3
id: cache-build
env:
cache-name: prod-build
key-1: ${{ hashFiles('pnpm-lock.yaml') }}
key-2: ${{ hashFiles('apps/**/**.[jt]s', 'apps/**/**.[jt]sx', 'packages/**/**.[jt]s', 'packages/**/**.[jt]sx', '!**/node_modules') }}
key-3: ${{ github.event.pull_request.number || github.ref }}
with:
path: |
${{ github.workspace }}/apps/web/.next
**/.turbo/**
**/dist/**
key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}-${{ env.key-3 }}
- name: Setup Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 20.x
if: steps.cache-build.outputs.cache-hit != 'true'
- name: Install pnpm
uses: pnpm/action-setup@v2
if: steps.cache-build.outputs.cache-hit != 'true'
- name: Install dependencies
run: pnpm install --config.platform=linux --config.architecture=x64
if: steps.cache-build.outputs.cache-hit != 'true'
shell: bash
- name: create .env
run: cp .env.example .env
shell: bash
- name: Generate Random ENCRYPTION_KEY
run: |
SECRET=$(openssl rand -hex 32)
echo "ENCRYPTION_KEY=$SECRET" >> $GITHUB_ENV
shell: bash
- run: |
pnpm build --filter=web...
if: steps.cache-build.outputs.cache-hit != 'true'
shell: bash

View File

@@ -0,0 +1,10 @@
name: Dangerous git Checkout
description: "Git Checkout from PR code so we can run checks from forks"
runs:
using: "composite"
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 2

View File

@@ -1,4 +1,4 @@
name: Build
name: Build formbricks-com
on:
workflow_call:
jobs:
@@ -11,10 +11,10 @@ jobs:
- name: Checkout repo
uses: actions/checkout@v3
- name: Setup Node.js 18.x
- name: Setup Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 20.x
- name: Install pnpm
uses: pnpm/action-setup@v2

View File

@@ -1,4 +1,4 @@
name: Build
name: Build web
on:
workflow_call:
jobs:
@@ -8,13 +8,13 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout repo
uses: actions/checkout@v3
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- name: Setup Node.js 18.x
- name: Setup Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 20.x
- name: Install pnpm
uses: pnpm/action-setup@v2
@@ -25,7 +25,7 @@ jobs:
- name: create .env
run: cp .env.example .env
- name: Generate Random NEXTAUTH_SECRET
- name: Generate Random ENCRYPTION_KEY
run: |
SECRET=$(openssl rand -hex 32)
echo "ENCRYPTION_KEY=$SECRET" >> $GITHUB_ENV

View File

@@ -4,8 +4,8 @@ on:
# "Scheduled workflows run on the latest commit on the default or base branch."
# — https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#schedule
schedule:
# This will run the job at 22:00 UTC every day of every month.
- cron: "0 22 * * *"
# This will run the job at 20:00 UTC every day of every month.
- cron: "0 20 * * *"
jobs:
cron-reportUsageToStripe:
env:

75
.github/workflows/e2e.yml vendored Normal file
View File

@@ -0,0 +1,75 @@
name: E2E Tests
on:
workflow_call:
workflow_dispatch:
jobs:
build:
name: Run E2E Tests
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- name: Build & Cache Web Binaries
uses: ./.github/actions/cache-build-web
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Install dependencies
run: pnpm install
- name: Start PostgreSQL
run: |
cd packages/database && pnpm db:up &
for attempt in {1..20}; do
if nc -zv localhost 5432; then
echo "Ready"
break
fi
echo "Waiting..."
sleep 5
done
pnpm db:migrate:dev
- name: Serve packages for lazy loading
run: |
cd packages/surveys && pnpm serve &
- name: Run App
run: |
NODE_ENV=test pnpm start --filter=web &
for attempt in {1..20}; do
if [ $(curl -o /dev/null -s -w "%{http_code}" http://localhost:3000/health) -eq 200 ]; then
echo "Ready"
break
fi
echo "Waiting..."
sleep 10
done
- name: Test Serve endpoints
run: |
curl -s http://localhost:3003
- name: Cache Playwright
uses: actions/cache@v3
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('pnpm-lock.yaml') }}
- name: Install Playwright
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: pnpm exec playwright install --with-deps
- name: Run E2E Tests
run: |
pnpm test:e2e
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30

129
.github/workflows/ecs-deployment.yml vendored Normal file
View File

@@ -0,0 +1,129 @@
name: ECS
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
on:
push:
branches: [main]
workflow_dispatch: # Add manual trigger support
env:
REGISTRY: ghcr.io
IMAGE_NAME: formbricks/formbricks-experimental
DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/formbricks?schema=public"
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write # Only necessary for sigstore/fulcio outside PRs
steps:
- name: Generate Secrets
run: |
echo "NEXTAUTH_SECRET=$(openssl rand -hex 32)" >> $GITHUB_ENV
echo "ENCRYPTION_KEY=$(openssl rand -hex 32)" >> $GITHUB_ENV
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Depot CLI
uses: depot/setup-action@v1
# https://github.com/sigstore/cosign-installer
- name: Install cosign
uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1
with:
cosign-release: "v2.1.1"
# https://github.com/docker/login-action
- name: Log into registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha,format=long
# Build and push Docker image with Buildx
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: depot/build-push-action@v1
env:
NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.NEXT_PUBLIC_SENTRY_DSN }}
with:
project: tw0fqmsx3c
token: ${{ secrets.DEPOT_PROJECT_TOKEN }}
context: .
file: ./apps/web/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
NEXTAUTH_SECRET=${{ env.NEXTAUTH_SECRET }}
DATABASE_URL=${{ env.DATABASE_URL }}
ENCRYPTION_KEY=${{ env.ENCRYPTION_KEY }}
NEXT_PUBLIC_SENTRY_DSN=${{ env.NEXT_PUBLIC_SENTRY_DSN }}
- name: Sign the images with GitHub OIDC Token
env:
DIGEST: ${{ steps.build-and-push.outputs.digest }}
TAGS: ${{ steps.meta.outputs.tags }}
run: |
images=""
for tag in ${TAGS}; do
images+="${tag}@${DIGEST} "
done
cosign sign --yes ${images}
outputs:
image_tag_sha: ${{ steps.meta.outputs.tags }}
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Download task definition
run: |
aws ecs describe-task-definition --task-definition prod-webapp-ecs-service --query taskDefinition > task-definition.json
- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition.json
container-name: prod-webapp-container
image: ${{ needs.build.outputs.image_tag_sha }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: prod-webapp-ecs-service
cluster: prod-core-infra-ecs-cluster
wait-for-service-stability: true

View File

@@ -8,8 +8,8 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v3
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- name: Setup Node.js 18.x
uses: actions/setup-node@v3

View File

@@ -1,40 +0,0 @@
name: E2E Tests
on:
workflow_call:
jobs:
build:
name: Run E2E Tests
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- name: Install Docker Compose
run: sudo apt-get update && sudo apt-get install -y docker-compose
- name: Install dependencies
run: npm install -g pnpm && pnpm install
- name: Build Formricks JS package
run: pnpm build --filter=js
- name: Build Formbricks Image & Run
run: docker-compose up -d
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps
- name: Run Playwright tests
run: pnpm test:e2e
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30

View File

@@ -12,24 +12,49 @@ concurrency:
cancel-in-progress: true
jobs:
changes:
name: Detect changes
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
has-files-requiring-all-checks: ${{ steps.filter.outputs.has-files-requiring-all-checks }}
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
has-files-requiring-all-checks:
- "!(**.md|.github/CODEOWNERS)"
test:
name: Run Tests
needs: [changes]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/test.yml
secrets: inherit
lint:
name: Run Linters
needs: [changes]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/lint.yml
secrets: inherit
build:
name: Build Formbricks-web
needs: [changes]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/build-web.yml
secrets: inherit
e2e-test:
name: Run E2E Tests
uses: ./.github/workflows/playwright.yml
needs: [changes]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e.yml
secrets: inherit
required:

View File

@@ -0,0 +1,70 @@
name: Docker for Data Migrations
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
on:
workflow_dispatch:
push:
tags:
- "v*"
env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
IMAGE_NAME: formbricks/data-migrations
DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/formbricks?schema=public"
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1
with:
cosign-release: "v2.1.1"
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=tag
type=raw,value=${{ github.ref_name }}
- name: Build and push Docker image
uses: docker/build-push-action@v3
with:
context: .
file: ./packages/database/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
DATABASE_URL=${{ env.DATABASE_URL }}
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
run: |
cosign sign --yes ghcr.io/${{ env.IMAGE_NAME }}:${{ github.ref_name }}

View File

@@ -44,6 +44,9 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Depot CLI
uses: depot/setup-action@v1
# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
@@ -52,17 +55,6 @@ jobs:
with:
cosign-release: "v2.1.1"
# Add support for more platforms with QEMU (optional)
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 # v3.0.0
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
@@ -85,11 +77,13 @@ jobs:
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v5 # v5.0.0
uses: depot/build-push-action@v1
with:
project: tw0fqmsx3c
token: ${{ secrets.DEPOT_PROJECT_TOKEN }}
context: .
file: ./apps/web/Dockerfile
# platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -7,18 +7,14 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
steps:
- name: Checkout repo
uses: actions/checkout@v3
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- name: Setup Node.js 18.x
- name: Setup Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 18.x
node-version: 20.x
- name: Install pnpm
uses: pnpm/action-setup@v2
@@ -34,8 +30,5 @@ jobs:
SECRET=$(openssl rand -hex 32)
echo "ENCRYPTION_KEY=$SECRET" >> $GITHUB_ENV
- name: Build formbricks-js dependencies
run: pnpm build --filter=js
- name: Test
run: pnpm test

3
.gitignore vendored
View File

@@ -51,3 +51,6 @@ Zone.Identifier
/playwright-report/
/blob-report/
/playwright/.cache/
# uploads
packages/lib/uploads

110
README.md
View File

@@ -1,50 +1,46 @@
<div id="top"></div>
<div id="top"></div>
<p align="center">
<p align="center">
<a href="https://formbricks.com">
<a href="https://formbricks.com">
<img width="120" alt="Open Source Privacy First Experience Management Solution Qualtrics Alternative Logo" src="https://github.com/formbricks/formbricks/assets/72809645/0086704f-bee7-4d38-9cc8-fa42ee59e004">
<img width="120" alt="Open Source Privacy First Experience Management Solution Qualtrics Alternative Logo" src="https://github.com/formbricks/formbricks/assets/72809645/0086704f-bee7-4d38-9cc8-fa42ee59e004">
</a>
<h3 align="center">Formbricks</h3>
<h3 align="center">Formbricks</h3>
<p align="center">
<p align="center">
Harvest user-insights, build irresistible experiences.
<br />
<a href="https://formbricks.com/">Website</a> | <a href="https://formbricks.com/discord">Join Discord community</a>
<br />
<a href="https://formbricks.com/">Website</a> | <a href="https://formbricks.com/discord">Join Discord community</a>
</p>
</p>
<p align="center">
<a href="https://github.com/formbricks/formbricks/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-AGPL-purple" alt="License"></a> <a href="https://formbricks.com/discord"><img src="https://img.shields.io/discord/979077669410979880?label=Discord&logo=discord&logoColor=%23fff" alt="Join Formbricks Discord"></a> <a href="https://github.com/formbricks/formbricks/stargazers"><img src="https://img.shields.io/github/stars/formbricks/formbricks?logo=github" alt="Github Stars"></a>
<a href="https://news.ycombinator.com/item?id=32303986"><img src="https://img.shields.io/badge/Hacker%20News-122-%23FF6600" alt="Hacker News"></a>
<a href="[https://www.producthunt.com/products/formbricks](https://www.producthunt.com/posts/formbricks)"><img src="https://img.shields.io/badge/Product%20Hunt-455-orange?logo=producthunt&logoColor=%23fff" alt="Product Hunt"></a>
<a href="https://github.blog/2023-04-12-github-accelerator-our-first-cohort-and-whats-next/"><img src="https://img.shields.io/badge/2023-blue?logo=github&label=Github%20Accelerator" alt="Github Accelerator"></a>
<a href="https://github.com/formbricks/formbricks/issues?q=is:issue+is:open+label:%22%F0%9F%99%8B%F0%9F%8F%BB%E2%80%8D%E2%99%82%EF%B8%8Fhelp+wanted%22"><img src="https://img.shields.io/badge/Help%20Wanted-Contribute-blue"></a>
<p align="center">
<a href="https://github.com/formbricks/formbricks/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-AGPL-purple" alt="License"></a> <a href="https://formbricks.com/discord"><img src="https://img.shields.io/discord/979077669410979880?label=Discord&logo=discord&logoColor=%23fff" alt="Join Formbricks Discord"></a> <a href="https://github.com/formbricks/formbricks/stargazers"><img src="https://img.shields.io/github/stars/formbricks/formbricks?logo=github" alt="Github Stars"></a>
<a href="https://news.ycombinator.com/item?id=32303986"><img src="https://img.shields.io/badge/Hacker%20News-122-%23FF6600" alt="Hacker News"></a>
<a href="[https://www.producthunt.com/products/formbricks](https://www.producthunt.com/posts/formbricks)"><img src="https://img.shields.io/badge/Product%20Hunt-455-orange?logo=producthunt&logoColor=%23fff" alt="Product Hunt"></a>
<a href="https://github.blog/2023-04-12-github-accelerator-our-first-cohort-and-whats-next/"><img src="https://img.shields.io/badge/2023-blue?logo=github&label=Github%20Accelerator" alt="Github Accelerator"></a>
<a href="https://github.com/formbricks/formbricks/issues?q=is:issue+is:open+label:%22%F0%9F%99%8B%F0%9F%8F%BB%E2%80%8D%E2%99%82%EF%B8%8Fhelp+wanted%22"><img src="https://img.shields.io/badge/Help%20Wanted-Contribute-blue"></a>
</p>
<br/>
<div style="background-color:#f8fafc; border-radius:5px;">
<p align="center">
<i>Trusted by</i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://flixbus.com"><img src="https://github.com/formbricks/formbricks/assets/72809645/d6c91d89-7633-4845-ae1e-03bbd2ce0946" height="35px"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://github.com/calcom/cal.com/"><img src="https://github.com/formbricks/formbricks/assets/675065/1a8763cf-f47e-4960-90f6-334f6dc12a17#gh-light-mode-only" height="20px"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://github.com/CrowdDotDev/crowd.dev"><img src="https://github.com/formbricks/formbricks/assets/675065/59b1a4d4-25e4-4ef3-b0bf-4426446fbfd0#gh-light-mode-only" height="20px"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://neverinstall.com/"><img src="https://github.com/formbricks/formbricks/assets/675065/72e5e37b-8ef7-4340-b06e-f1d12a05330f#gh-light-mode-only" height="20px"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://clovyr.io/"><img src="https://github.com/formbricks/formbricks/assets/675065/9291c8df-9aac-423a-a430-a9a581240075" height="20px"></a>
<p align="center">
<i>Trusted by</i><br/>
<img width="867" alt="clients-hi-res" src="https://github.com/formbricks/formbricks/assets/72809645/924d3693-f66a-4063-bb31-6e5789a8175a">
</p>
<div>
<p align="center">
<a href="https://trendshift.io/repositories/2570" target="_blank"><img src="https://trendshift.io/api/badge/repositories/2570" alt="Trendshift Badge for formbricks/formbricks" style="width: 250px; height: 55px;" width="250" height="55"/></a>
<p align="center">
<a href="https://trendshift.io/repositories/2570" target="_blank"><img src="https://trendshift.io/api/badge/repositories/2570" alt="Trendshift Badge for formbricks/formbricks" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</p>
## ✨ About Formbricks
<img width="1527" alt="formbricks-sneak" src="https://github-production-user-asset-6210df.s3.amazonaws.com/675065/249441967-ccb89ea3-82b4-4bf2-8d2c-528721ec313b.png">
<img width="1527" alt="formbricks-sneak" src="https://github-production-user-asset-6210df.s3.amazonaws.com/675065/249441967-ccb89ea3-82b4-4bf2-8d2c-528721ec313b.png">
Formbricks provides a free and open source surveying platform. Gather feedback at every point in the user journey with beautiful in-app, website, link and email surveys. Build on top of Formbricks or leverage prebuilt data analysis capabilities.
@@ -70,11 +66,11 @@ Formbricks is both a free and open source survey platform - and a privacy-first
- [Contact](#contact-us)
- [License](#license)
- [Security](#security)
<a id="features"></a>
- [License](#license)
<a id="features"></a>
### Features
@@ -108,26 +104,26 @@ Formbricks is both a free and open source survey platform - and a privacy-first
- 🧘‍♂️ [Zod](https://zod.dev/)
<a id="getting-started"></a>
- 🐛 [Vitest](https://vitest.dev/)
<a id="getting-started"></a>
## 🚀 Getting started
We've got several options depending on your need to help you quickly get started with Formbricks.
<a id="cloud-version"></a>
<a id="cloud-version"></a>
### ☁️ Cloud Version
Formbricks has a hosted cloud offering with a generous free plan to get you up and running as quickly as possible. To get started, please visit [formbricks.com](https://app.formbricks.com/auth/signup).
<a id="self-hosted-version"></a>
<a id="self-hosted-version"></a>
### 🐳 Self-hosting Formbricks
Formbricks is available Open-Source under AGPLv3 license. You can host Formbricks on your own servers using Docker without a subscription.
(In the future we may develop additional features that aren't in the free Open-Source version).
If you opt for self-hosting Formbricks, here are a few options to consider:
#### Docker
@@ -142,11 +138,11 @@ You can deploy Formbricks on [Railway](https://railway.app) using the button bel
[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/PPDzCd)
<a id="development"></a>
<a id="development"></a>
### 👨‍💻 Development
## 👨‍💻 Development
#### Prerequisites
### Prerequisites
Here is what you need to be able to run Formbricks:
@@ -156,11 +152,11 @@ Here is what you need to be able to run Formbricks:
- [Docker](https://www.docker.com/) - to run PostgreSQL and MailHog
#### Local Setup
### Local Setup
To get started locally, we've got a [guide to help you](https://formbricks.com/docs/contributing/setup).
#### Gitpod Setup
### Gitpod Setup
1. Click the button below to open this project in Gitpod.
@@ -168,7 +164,7 @@ To get started locally, we've got a [guide to help you](https://formbricks.com/d
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/formbricks/formbricks)
<a id="contribution"></a>
<a id="contribution"></a>
## ✍️ Contribution
@@ -186,30 +182,46 @@ Please check out [our contribution guide](https://formbricks.com/docs/contributi
## All Thanks To Our Contributors
<a href="https://github.com/formbricks/formbricks/graphs/contributors">
<a href="https://github.com/formbricks/formbricks/graphs/contributors">
<img src="https://contrib.rocks/image?repo=formbricks/formbricks" />
<img src="https://contrib.rocks/image?repo=formbricks/formbricks" />
</a>
<a id="contact-us"></a>
<a id="contact-us"></a>
## 📆 Contact us
Let's have a chat about your survey needs and get you started.
<a href="https://cal.com/johannes/onboarding?utm_source=banner&utm_campaign=oss"><img alt="Book us with Cal.com" src="https://cal.com/book-with-cal-dark.svg" /></a>
<a href="https://cal.com/johannes/onboarding?utm_source=banner&utm_campaign=oss"><img alt="Book us with Cal.com" src="https://cal.com/book-with-cal-dark.svg" /></a>
<a id="license"></a>
<a id="license"></a>
## ⚖️ License
Distributed under the AGPLv3 License. See [`LICENSE`](./LICENSE) for more information.
<a id="security"></a>
<a id="security"></a>
## 🔒 Security
We take security very seriously. If you come across any security vulnerabilities, please disclose them by sending an email to security@formbricks.com. We appreciate your help in making our platform as secure as possible and are committed to working with you to resolve any issues quickly and efficiently. See [`SECURITY.md`](./SECURITY.md) for more information.
<p align="right"><a href="#top">🔼 Back to top</a></p>
<a id="license"></a>
## 👩‍⚖️ License
### The AGPL Formbricks Core
The Formbricks core application is licensed under the [AGPLv3 Open Source License](https://github.com/formbricks/formbricks/blob/main/LICENSE). The core application is fully functional and includes everything you need to design & run link surveys, website surveys and in-app surveys. You can use the software for free for personal and commercial use. You're also allowed to create and distribute modified versions as long as you document the changes you make incl. date. The AGPL license requires you to publish your modified version under the AGPLv3 license as well.
### The Enterprise Edition
Additional to the AGPL licensed Formbricks core, this repository contains code licensed under an Enterprise license. The [code](https://github.com/formbricks/formbricks/tree/main/packages/ee) and [license](https://github.com/formbricks/formbricks/blob/main/packages/ee/LICENSE) for the enterprise functionality can be found in the `/packages/ee` folder of this repository. This additional functionality is not part of the AGPLv3 licensed Formbricks core and is designed to meet the needs of larger teams and enterprises. This advanced functionality is already included in the Docker images, but you need an [Enterprise License Key](https://formbricks.com/docs/self-hosting/enterprise) to unlock it.
### White-Labeling Formbricks and Other Licensing Needs
If you have other licensing requirements such as White-Labeling please [send us an email](mailto:hola@formbricks.com).
### Why charge for Enterprise Features?
The Enterprise Edition and White-Label Licenses allow us to fund the development of Formbricks sustainably. It guarantees that the open-source surveying infrastructure we're building will be around for decades to come.
<p align="right"><a href="#top">🔼 Back to top</a></p>

View File

@@ -13,7 +13,7 @@
"dependencies": {
"@formbricks/js": "workspace:*",
"@heroicons/react": "^2.1.1",
"next": "14.0.4",
"next": "14.1.0",
"react": "18.2.0",
"react-dom": "18.2.0"
},

View File

@@ -2,7 +2,7 @@ import { Head, Html, Main, NextScript } from "next/document";
export default function Document() {
return (
<Html lang="en" className="h-full bg-gray-50">
<Html lang="en" className="h-full bg-slate-50">
<Head />
<body className="h-full">
<Main />

View File

@@ -23,13 +23,12 @@ export default function AppPage({}) {
useEffect(() => {
if (process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID && process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST) {
const isUserId = window.location.href.includes("userId=true");
const userId = isUserId ? "THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING" : undefined;
const attributes = isUserId ? { "Init Attribute 1": "eight", "Init Attribute 2": "two" } : undefined;
const userId = isUserId ? "THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING" : undefined;
formbricks.init({
environmentId: process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID,
apiHost: process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST,
userId,
debug: true,
attributes,
});
window.formbricks = formbricks;
@@ -100,22 +99,22 @@ export default function AppPage({}) {
</div>
<div className="md:grid md:grid-cols-3">
<div className="col-span-3 rounded-lg border border-slate-300 bg-slate-100 p-6 dark:border-gray-600 dark:bg-gray-800">
<div className="col-span-3 rounded-lg border border-slate-300 bg-slate-100 p-6 dark:border-slate-600 dark:bg-slate-800">
<h3 className="text-lg font-semibold dark:text-white">
Reset person / pull data from Formbricks app
</h3>
<p className="text-slate-700 dark:text-gray-300">
On formbricks.reset() a few things happen: <strong>New person is created</strong> and{" "}
<strong>surveys & no-code actions are pulled from Formbricks:</strong>.
<p className="text-slate-700 dark:text-slate-300">
On formbricks.reset() the local state will <strong>be deleted</strong> and formbricks gets{" "}
<strong>reinitialized</strong>.
</p>
<button
className="my-4 rounded-lg bg-slate-500 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600"
className="my-4 rounded-lg bg-slate-500 px-6 py-3 text-white hover:bg-slate-700 dark:bg-slate-700 dark:hover:bg-slate-600"
onClick={() => {
formbricks.reset();
}}>
Reset
</button>
<p className="text-xs text-slate-700 dark:text-gray-300">
<p className="text-xs text-slate-700 dark:text-slate-300">
If you made a change in Formbricks app and it does not seem to work, hit &apos;Reset&apos; and
try again.
</p>
@@ -124,7 +123,7 @@ export default function AppPage({}) {
<div className="p-6">
<div>
<button
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600"
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-slate-700 dark:hover:bg-slate-600"
onClick={() => {
formbricks.track("Code Action");
}}>
@@ -132,7 +131,7 @@ export default function AppPage({}) {
</button>
</div>
<div>
<p className="text-xs text-slate-700 dark:text-gray-300">
<p className="text-xs text-slate-700 dark:text-slate-300">
This button sends a{" "}
<a href="https://formbricks.com/docs/actions/code" className="underline" target="_blank">
Code Action
@@ -143,12 +142,12 @@ export default function AppPage({}) {
</div>
<div className="p-6">
<div>
<button className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
<button className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-slate-700 dark:hover:bg-slate-600">
No-Code Action
</button>
</div>
<div>
<p className="text-xs text-slate-700 dark:text-gray-300">
<p className="text-xs text-slate-700 dark:text-slate-300">
This button sends a{" "}
<a
href="https://formbricks.com/docs/actions/no-code"
@@ -172,12 +171,12 @@ export default function AppPage({}) {
onClick={() => {
formbricks.setAttribute("Plan", "Free");
}}
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-slate-700 dark:hover:bg-slate-600">
Set Plan to &apos;Free&apos;
</button>
</div>
<div>
<p className="text-xs text-slate-700 dark:text-gray-300">
<p className="text-xs text-slate-700 dark:text-slate-300">
This button sets the{" "}
<a
href="https://formbricks.com/docs/attributes/custom-attributes"
@@ -195,12 +194,12 @@ export default function AppPage({}) {
onClick={() => {
formbricks.setAttribute("Plan", "Paid");
}}
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-slate-700 dark:hover:bg-slate-600">
Set Plan to &apos;Paid&apos;
</button>
</div>
<div>
<p className="text-xs text-slate-700 dark:text-gray-300">
<p className="text-xs text-slate-700 dark:text-slate-300">
This button sets the{" "}
<a
href="https://formbricks.com/docs/attributes/custom-attributes"
@@ -218,12 +217,12 @@ export default function AppPage({}) {
onClick={() => {
formbricks.setEmail("test@web.com");
}}
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-slate-700 dark:hover:bg-slate-600">
Set Email
</button>
</div>
<div>
<p className="text-xs text-slate-700 dark:text-gray-300">
<p className="text-xs text-slate-700 dark:text-slate-300">
This button sets the{" "}
<a
href="https://formbricks.com/docs/attributes/identify-users"
@@ -242,7 +241,7 @@ export default function AppPage({}) {
onClick={() => {
window.location.href = "/app";
}}
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-slate-700 dark:hover:bg-slate-600">
Deactivate User Identification
</button>
</div>
@@ -252,13 +251,13 @@ export default function AppPage({}) {
onClick={() => {
window.location.href = "/app?userId=true";
}}
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-gray-700 dark:hover:bg-gray-600">
className="mb-4 rounded-lg bg-slate-800 px-6 py-3 text-white hover:bg-slate-700 dark:bg-slate-700 dark:hover:bg-slate-600">
Activate User Identification
</button>
</div>
)}
<div>
<p className="text-xs text-slate-700 dark:text-gray-300">
<p className="text-xs text-slate-700 dark:text-slate-300">
This button activates/deactivates{" "}
<a
href="https://formbricks.com/docs/attributes/identify-users"

View File

@@ -1,37 +0,0 @@
export const metadata = {
title: "Implementing Code Actions in Formbricks | Real-time User Action Tracking",
description:
"Dive into the world of Formbricks' code actions. Learn how to seamlessly integrate formbricks.track() method into your codebase, enabling real-time tracking of user actions like button clicks, visiting a specific URL. Up your survey game with precise and exact triggers.",
};
#### Actions
# Code Actions
Actions can also be set in the codebase to trigger surveys. Please add the code action first in the Formbricks web interface to be able to configure your surveys to use this action.
After that you can fire an action using `formbricks.track()`
<Col>
<CodeGroup title="Track an action">
```javascript
formbricks.track("Action Name");
```
</CodeGroup>
</Col>
Here is an example of how to fire an action when a user clicks a button:
<Col>
<CodeGroup title="Track Button Click">
```javascript
const handleClick = () => {
formbricks.track("Button Clicked");
};
return <button onClick={handleClick}>Click Me</button>;
```
</CodeGroup>
</Col>

View File

@@ -1,30 +0,0 @@
export const metadata = {
title: "Implementing No-Code Actions in Formbricks | Real-time User Action Tracking",
description:
"Discover the power of Formbricks' No-Code Actions. Easily set up triggers based on Page URL, innerText, and CSS Selectors without touching a line of code. Inccrease user engagement and get insights at precise moments in the user journey.",
};
#### Actions
# No-Code Actions
No-Code actions can be set up within Formbricks with just a few clicks. There are three types of No-Code actions:
## Page URL Action
The page URL action is triggered, when a user visits a specific page in your application. There are several match conditions:
- `exactMatch`: The URL should exactly match the provided string.
- `contains`: The URL should contain the specified string as a substring.
- `startsWith`: The URL should start with the specified string.
- `endsWith`: The URL should end with the specified string.
- `notMatch`: The URL should not match the specified condition.
- `notContains`: The URL should not contain the specified string as a substring.
## innerText Action
The innerText action checks if the `innerText` of a clicked HTML element matches a specific text, e.g. the label of a button. Display a survey on any button click!
## CSS Selector Action
The CSS Selector action checks if the provided CSS selector matches the selector of a clicked HTML element. The CSS selector can be a class, id or any other CSS selector within your website. Display a survey on any element click!

View File

@@ -1,23 +0,0 @@
export const metadata = {
title: "Using Actions in Formbricks | Fine-tuning User Moments",
description:
"Dive deep into how actions in Formbricks help products and teams to engage users at precise moments in their journey. Discover the power of actions, from coding to no-code setups, to refine user targeting and generate richer, more detailed user insights.",
};
#### Actions
# What are actions and why are they useful?
You want to understand what your users think and feel during specific moments in the user journey. To be able to ask at exactly the right point in time, you need actions.
## What are actions?
Actions are a little notification sent from your application to Formbricks. You decide which actions are sent either in your [Code](/docs/actions/code) or by setting up a [No-Code](/docs/actions/no-code) action within Formbricks.
## How do actions work?
When a predefined action happens in your app, the Formbricks widget notices. This action can then trigger a survey to be shown to the user and is stored in the database.
## Why are actions useful?
Actions help you to display your surveys at the right time. Later on, you will be able to segment your users based on the actions they have triggered in the past. This way, you can create much more granular user segments, e.g. only target users that already have used a specific feature.

View File

@@ -45,8 +45,7 @@ Adds an Actions for a given User by their User ID
curl --location --request POST 'https://app.formbricks.com/api/v1/client/<environment-id>/actions' \
--data-raw '{
"userId": "1",
"name": "new_action_v2",
"properties":{}
"name": "new_action_v2"
}'
```
@@ -54,8 +53,7 @@ Adds an Actions for a given User by their User ID
```json {{ title: 'Example Request Body' }}
{
"userId": "1",
"name": "new_action_v3",
"properties":{}
"name": "new_action_v3"
}
```

View File

@@ -1,14 +1,16 @@
import { Fence } from "@/components/shared/Fence";
import {generateManagementApiMetadata} from "@/lib/utils"
import { generateManagementApiMetadata } from "@/lib/utils";
export const metadata = generateManagementApiMetadata("Responses",["Fetch","Delete"])
export const metadata = generateManagementApiMetadata("Responses", ["Fetch", "Delete"]);
#### Management API
# Responses API
This set of API can be used to
- [List Responses](#list-all-responses)
- [List all Responses by surveyId](#list-all-responses-by-survey-id)
- [Get Response](#get-response-by-id)
- [Delete Response](#delete-a-response)
@@ -107,6 +109,97 @@ This set of API can be used to
---
## List all Responses by surveyId {{ tag: 'GET', label: '/api/v1/management/responses?surveyId=<survey-Id>' }}
<Row>
<Col>
Retrieve all the responses received in your survey.
### Mandatory Headers
<Properties>
<Property name="x-Api-Key" type="string">
Your Formbricks API key.
</Property>
</Properties>
</Col>
<Col sticky>
<CodeGroup title="Request" tag="GET" label="/api/v1/management/responses?surveyId=<survey-Id>">
```bash {{ title: 'cURL' }}
curl --location \
'https://app.formbricks.com/api/v1/management/responses?surveyId=<survey-Id>' \
--header \
'x-api-key: <your-api-key>'
```
</CodeGroup>
<CodeGroup title="Response">
```json {{title:'200 Success'}}
{
"data":[
{
"id": "cln8k0tqv00pcz87no4qrw333",
"createdAt": "2023-10-02T07:13:20.023Z",
"updatedAt": "2023-10-02T07:13:20.023Z",
"surveyId": "cln8k0tqu00p7z87nqr4thi3k",
"finished": true,
"data": {
"interview-prompt": "clicked"
},
"meta": {
"userAgent": {
"os": "MacOS",
"browser": "Chrome"
}
},
"personAttributes": null,
"person": {
"id": "e0x4i5tvsp8puxfztyrwykvn",
"attributes": {
"userId": "CYO675",
"email": "ravi@netflix.com",
"Name": "Ravi Kumar",
"Role": "Manager",
"Company": "Netflix",
"Experience": "6 years",
"Usage Frequency": "Monthly",
"Company Size": "4610 employees",
"Product Satisfaction Score": "43",
"Recommendation Likelihood": "4"
},
"environmentId": "cln8k0t47000fz87njmmu2bck",
"createdAt": "2023-10-02T07:13:19.444Z",
"updatedAt": "2023-10-02T07:13:19.444Z"
},
"notes": [],
"tags": []
},
]
}
```
```json {{ title: '401 Not Authenticated' }}
{
"code": "not_authenticated",
"message": "Not authenticated",
"details": {
"x-Api-Key": "Header not provided or API Key invalid"
}
}
```
</CodeGroup>
</Col>
</Row>
---
## Get Response by ID {{ tag: 'GET', label: '/api/v1/management/responses/<response-id>' }}
<Row>

View File

@@ -1,57 +0,0 @@
export const metadata = {
title: "Guide for Setting Custom Attributes | Formbricks Documentation",
description:
"Learn how to set attributes in code using setAttribute function. Enhance user segmentation, target surveys effectively, and gather valuable insights for better decisions. Easily send user-specific details for better survey segmentation and gain deeper insights.",
};
#### Attributes
# Setting attributes with code
One way to send attributes to Formbricks is in your code. In Formbricks, there are two special attributes for [user identification](/docs/attributes/identify-users)(user ID & email) and custom attributes. An example:
## Setting during Initialization
It's recommended to set custom user attributes directly during the initialization of Formbricks for better user identification.
<Col>
<CodeGroup title="Set custom attributes during initialization">
```javascript
formbricks.init({
environmentId: "<environment-id>",
apiHost: "<api-host>",
userId: "<user_id>",
attributes: {
plan: "free",
},
});
```
</CodeGroup>
</Col>
## Setting independently
You can use the setAttribute function to set any custom attribute for the user (e.g. name, plan, etc.) anywhere in the user journey. Formbricks maintains a state of the current user inside the browser and makes sure attributes aren't sent to the backend twice.
<Col>
<CodeGroup title="Setting Plan to Pro">
```javascript
formbricks.setAttribute("Plan", "Pro");
```
</CodeGroup>
</Col>
Generally speaking, the setAttribute function works like this:
<Col>
<CodeGroup title="Setting Custom Attributes">
```javascript
formbricks.setAttribute("attribute_key", "attribute_value");
```
</CodeGroup>
</Col>
Where `attributeName` is the name of the attribute you want to set, and `attributeValue` is the value of the attribute you want to set.

View File

@@ -1,23 +0,0 @@
export const metadata = {
title: "Understanding User Attributes in Formbricks Surveys",
description:
"Dive into the importance of attributes in surveys. Learn how key-value pairs can significantly improve survey targeting, enhance feedback quality, and guide data-driven decisions with Formbricks.",
};
#### Attributes
# What are attributes and why are they useful?
Surveying your user base without segmentation leads to weak results and survey fatigue. Attributes help you segment your users into groups.
## What are attributes?
Attributes are key-value pairs that you can set for each person individually. For example, the attribute "Plan" can be set to "Free" or "Paid".
## How do attributes work?
Attributes are sent from your application to Formbricks and are associated with the current user. We store it in our database and allow you to use it the next time you create a survey.
## Why are attributes useful?
Attributes help show surveys to the right group of people. For example, you can show a survey to all users who have a "Plan" attribute set to "Paid".

View File

@@ -46,7 +46,8 @@ To run the Churn Survey in your app you want to proceed as follows:
4. Prevent that churn!
<Note>
## Formbricks Widget running? We assume that you have already installed the Formbricks Widget in your web
## Formbricks Widget running?
We assume that you have already installed the Formbricks Widget in your web
app. Its required to display messages and surveys in your app. If not, please follow the [Quick Start Guide
(takes 15mins max.)](/docs/getting-started/quickstart-in-app-survey)
</Note>
@@ -119,7 +120,8 @@ Whenever a user visits this page, matches the filter conditions above and the re
Here is our complete [Actions manual](/docs/actions/why) covering [Code](/docs/actions/code) and [No-Code](/docs/actions/no-code) Actions.
<Note>
## Pre-churn flow coming soon Were currently building full-screen survey pop-ups. Youll be able to prevent
## Pre-churn flow coming soon
Were currently building full-screen survey pop-ups. Youll be able to prevent
users from closing the survey unless they respond to it. Its certainly debatable if you want that but you
could force them to click through the survey before letting them cancel 🤷
</Note>
@@ -156,7 +158,8 @@ These settings make sure the survey is always displayed, when a user wants to Ca
/>
<Note>
## Formbricks Widget running? You need to have the Formbricks Widget installed to display the Churn Survey
## Formbricks Widget running?
You need to have the Formbricks Widget installed to display the Churn Survey
in your app. Please follow [this tutorial (Step 4 onwards)](/docs/getting-started/quickstart-in-app-survey)
to install the widget.
</Note>

View File

@@ -43,7 +43,8 @@ To run the Feature Chaser survey in your app you want to proceed as follows:
2. Setup a user action to display survey at the right point in time
<Note>
## Formbricks Widget running? We assume that you have already installed the Formbricks Widget in your web
## Formbricks Widget running?
We assume that you have already installed the Formbricks Widget in your web
app. Its required to display messages and surveys in your app. If not, please follow the [Quick Start Guide
(takes 15mins max.)](/docs/getting-started/quickstart-in-app-survey)
</Note>
@@ -127,7 +128,8 @@ Lastly, scroll down to “Recontact Options”. Here you have full freedom to de
<Image src={Publish} alt="Publish survey" quality="100" className="max-w-full rounded-lg sm:max-w-3xl" />
<Note>
## Formbricks Widget running? You need to have the Formbricks Widget installed to display the Feature Chaser
## Formbricks Widget running?
You need to have the Formbricks Widget installed to display the Feature Chaser
in your app. Please follow [this tutorial (Step 4 onwards)](/docs/getting-started/quickstart-in-app-survey)
to install the widget.
</Note>

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@@ -0,0 +1,113 @@
import DemoPreview from "@/components/dummyUI/DemoPreview";
import Image from "next/image";
import NewsletterSurveyType from './choose-survey-type.webp';
import NewsletterSurveyEmbedCode from './embed-survey-code-in-your-email.webp';
import NewsletterSurveyEmbedPrompt from './embed-survey-prompt.webp';
import NewsletterSurveyEditor from './improve-newsletter-content-editor-formbricks.webp';
import NewsletterSurvey from './improve-newsletter-content-survey-location.webp';
export const metadata = {
title: "Measure email content quality with Formbricks",
description:
"Measuring the content quality of both transactional and marketing email is a key element for improving customer communication.",
};
#### Best Practices
# Improve Email Content
Email remains the predominant way to communicate with your customers. Measure the effectiveness to improve your offering.
## Purpose
Measuring the content quality of both transactional and marketing email is a key element for improving customer communication.
## Preview
<DemoPreview template="Improve Newsletter Content" />
## Formbricks Approach
- Embed the survey into your email so its part of the newsletter.
- Use link prefilling to store the answer users clicked on in the email.
- Dynamic user identification to append reader's email for personalized profiles and follow ups.
## Installation
To embed the newsletter survey into your email, follow these steps:
1. Create new 'Improve Newsletter Content' survey at [app.formbricks.com](https://app.formbricks.com/)
2. Select how you where you want to display the survey.
3. Copy the embed code anywhere you want in your newsletter.
### 1. Create new 'Improve Newsletter Content' Survey
If you don't have an account yet, create one at [app.formbricks.com](https://app.formbricks.com/auth/signup)
Then, create a new survey and look for the "Improve Newsletter Content" template:
<Image
src={NewsletterSurvey}
alt="Create Improve Newsletter Content by template"
quality="100"
className="rounded-lg max-w-full sm:max-w-3xl"
/>
### 2. Customize Survey questions
Customize survey questions, emojis or stars however you like:
<Image
src={NewsletterSurveyEditor}
alt="Edit Improve Newsletter Content template"
quality="100"
className="rounded-lg max-w-full sm:max-w-3xl"
/>
### 3. Configure Survey Settings
When you are done customizing your survey questions, navigate to the Settings tab and choose the type of survey you want. You need to choose Link Survey:
<Image
src={NewsletterSurveyType}
alt="Choose survey type"
quality="100"
className="rounded-lg max-w-full sm:max-w-3xl"
/>
### 4. Choose how you want to embed your survey
After publishing your survey, a modal that prompts you to embed your survey will pop up.
<Image
src={NewsletterSurveyEmbedPrompt}
alt="Embed newsletter survey"
quality="100"
className="rounded-lg max-w-full sm:max-w-3xl"
/>
Select the Embed Survey card and you will be directed to another modal, where the first embed option displayed will be to embed the survey in an email.
### 5. Copy code to embed the survey in your newsletter
Click the button with the “View Embed Code” text at the top right corner of the modal and simply paste the HTML code for your survey anywhere you want it in your newsletter. You can see the preview in the below image:
<Image
src={NewsletterSurveyEmbedCode}
alt="Embed survey code"
quality="100"
className="rounded-lg max-w-full sm:max-w-3xl"
/>
And you're done! Send a test email to yourself and try it out 🤓
## Learn about data prefilling
<Note>
## How does data prefilling work?
Learn about how link prefilling and user identification maximize your insights in [this detailed guide](/blog/how-smart-writers-use-formbricks-open-source-tool-to-measure-the-quality-of-their-newsletter-content).
</Note>
### &nbsp;
# Thats it! 🎉

View File

@@ -43,7 +43,8 @@ To display the Trial Conversion Survey in your app you want to proceed as follow
3. Print that 💸
<Note>
## Formbricks Widget running? We assume that you have already installed the Formbricks Widget in your web
## Formbricks Widget running?
We assume that you have already installed the Formbricks Widget in your web
app. Its required to display messages and surveys in your app. If not, please follow the [Quick Start Guide
(takes 15mins max.)](/docs/getting-started/quickstart-in-app-survey)
</Note>
@@ -79,7 +80,8 @@ Save, and move over to the “Audience” tab.
### 3. Pre-segment your audience (coming soon)
<Note>
## Filter by attribute coming soon We're working on pre-segmenting users by attributes. We will update this
## Filter by attribute coming soon
We're working on pre-segmenting users by attributes. We will update this
manual in the next days.
</Note>
@@ -136,7 +138,8 @@ Lastly, scroll down to “Recontact Options”. Here you have to choose the corr
<Image src={Publish} alt="Publish survey" quality="100" className="max-w-full rounded-lg sm:max-w-3xl" />
<Note>
## Formbricks Widget running? You need to have the Formbricks Widget installed to display the Feedback Box
## Formbricks Widget running?
You need to have the Formbricks Widget installed to display the Feedback Box
in your app. Please follow [this tutorial (Step 4 onwards)](/docs/getting-started/quickstart-in-app-survey)
to install the widget.
</Note>

View File

@@ -48,7 +48,8 @@ To display an Interview Prompt in your app you want to proceed as follows:
3. Thats it! 🎉
<Note>
## Formbricks Widget running? We assume that you have already installed the Formbricks Widget in your web
## Formbricks Widget running?
We assume that you have already installed the Formbricks Widget in your web
app. Its required to display messages and surveys in your app. If not, please follow the [Quick Start Guide
(15mins).](/docs/getting-started/quickstart-in-app-survey)
</Note>
@@ -91,7 +92,8 @@ Save, and move over to the “Audience” tab.
### 3. Pre-segment your audience (coming soon)
<Note>
## Filter by attribute coming soon We're working on pre-segmenting users by attributes. We will update this
## Filter by attribute coming soon
We're working on pre-segmenting users by attributes. We will update this
manual in the next few days.
</Note>
@@ -108,7 +110,8 @@ To create the trigger to show your Interview Prompt, go to the “Audience” ta
<Image src={AddAction} alt="Add action" quality="100" className="max-w-full rounded-lg sm:max-w-3xl" />
<Note>
## You can also add actions in your code You can also create [Code Actions](/docs/actions/code) using
## You can also add actions in your code
You can also create [Code Actions](/docs/actions/code) using
`formbricks.track("Eventname")` - they will automatically appear in your Actions overview as long as the SDK
is embedded.
</Note>
@@ -161,7 +164,8 @@ Scroll down to “Recontact Options”. Here you have to choose the correct sett
<Image src={Publish} alt="Publish survey" quality="100" className="max-w-full rounded-lg sm:max-w-3xl" />
<Note>
## Formbricks Widget running? You need to have the Formbricks Widget installed to display the Feedback Box
## Formbricks Widget running?
You need to have the Formbricks Widget installed to display the Feedback Box
in your app. Please follow [this tutorial (Step 4 onwards)](/docs/getting-started/quickstart-in-app-survey)
to install the widget.
</Note>

View File

@@ -42,7 +42,8 @@ To display the Product-Market Fit survey in your app you want to proceed as foll
3. Setup the user action to display survey at good point in time
<Note>
## Formbricks Widget running? We assume that you have already installed the Formbricks Widget in your web
## Formbricks Widget running?
We assume that you have already installed the Formbricks Widget in your web
app. Its required to display messages and surveys in your app. If not, please follow the [Quick Start Guide
(15mins).](/docs/getting-started/quickstart-in-app-survey)
</Note>
@@ -78,7 +79,8 @@ Save, and move over to where the magic happens: The “Audience” tab.
### 3. Pre-segment your audience (coming soon)
<Note>
## Filter by attribute coming soon We're working on pre-segmenting users by attributes. We will update this
## Filter by attribute coming soon
We're working on pre-segmenting users by attributes. We will update this
manual in the next days.
</Note>
@@ -139,7 +141,8 @@ Lastly, scroll down to “Recontact Options”. Here you have to choose the corr
<Image src={Publish} alt="Publish survey" quality="100" className="max-w-full rounded-lg sm:max-w-3xl" />
<Note>
## Formbricks Widget running? You need to have the Formbricks Widget installed to display the Feedback Box
## Formbricks Widget running?
You need to have the Formbricks Widget installed to display the Feedback Box
in your app. Please follow [this tutorial (Step 4 onwards)](/docs/getting-started/quickstart-in-app-survey)
to install the widget.
</Note>

View File

@@ -1,4 +1,5 @@
import Image from "next/image";
import CorsHandling from "./cors-handling-in-api.webp";
export const metadata = {
@@ -25,7 +26,7 @@ Thank you for choosing to contribute to Formbricks. Before you start, please fam
- Constants should be in the packages folder
- Types should be in the packages folder
- How we handle Pull Requests
- Read environment variables from `.env.mjs`
- Read server-side environment variables from `constants.ts`
---
@@ -83,9 +84,9 @@ You should store constants in `packages/lib/constants`
You should store type in `packages/types`
## Read environment variables from `.env.mjs`
## Read server-side environment variables from `constants.ts`
Environment variables (`process.env`) shouldnt be accessed directly but be added in the `.env.mjs` and should be accessed from here. This practice helps us ensure that the variables are typesafe.
Server-side environment variables (`process.env`) shouldnt be accessed directly but included into the `constants.ts` file and read from there. This way we can assure they are used only on the server side and are also type-safe.
## How we handle Pull Requests

View File

@@ -42,6 +42,4 @@ If you are at all unsure, just raise it as an enhancement issue first and tell u
To be able to keep working on Formbricks over the coming years, we need to collect a CLA from all relevant contributors.
Please note that we can only get your contribution merged when we have a CLA signed by you.
To access the CLA form, please click [here](https://formbricks.com/clmyhzfrymr4ko00hycsg1tvx)
Once you open a PR, you will get a message from the CLA bot to fill out the form. Please note that we can only get your contribution merged when we have a CLA signed by you.

View File

@@ -63,7 +63,7 @@ This will install the Formbricks codebase and all the dependencies on your local
1. Wait for the web and demo apps to launch on Gitpod. This automatically opens the `apps/demo/.env` file. Utilize dynamic localhost URLs (e.g., `localhost:3000` for signup and `localhost:8025` for email confirmation) to configure `NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID`. After creating your account and finding the `ID` in the URL at `localhost:3000`, replace `YOUR_ENVIRONMENT_ID` in the `.env` file located in `app/demo`.
**Web Component Initialization:**
- we initialize the @formbricks/web component during prebuilds. This involves:
- We initialize the @formbricks/web component during prebuilds. This involves:
1. Installing build dependencies for the `@formbricks/web#go` task from turbo.json in prebuilds to save time.
2. Starting PostgreSQL and Mailhog containers for running migrations in prebuilds.
3. To prevent the "Init" task from running indefinitely due to prebuild rules, a cleanup `docker compose down` step i.e. `db:down` is added to `turbo.json`. This step is designed to halt the execution of containers that are currently running.
@@ -93,8 +93,8 @@ After clicking the one-click setup button, Gitpod will open a new tab or window.
### 2. Authorizing in Gitpod
<Image src={GitpodAuth} alt="Gitpod Auth Page" quality="100" className="max-w-full rounded-lg sm:max-w-3xl" />-
This is the Gitpod Authentication Page. It appears when you click the "Open in GitPod" button and Gitpod needs
<Image src={GitpodAuth} alt="Gitpod Auth Page" quality="100" className="max-w-full rounded-lg sm:max-w-3xl" />
- This is the Gitpod Authentication Page. It appears when you click the "Open in GitPod" button and Gitpod needs
to authenticate your access to the workspace. Click on 'Continue With Github' to authorize your GitPod session.
### 3. Creating a New Workspace
@@ -159,7 +159,7 @@ Here are the ports and corresponding URLs for the services within your Gitpod en
- **Port 1025**:
- **Service**: SMPT server
- **Service**: SMTP server
- **Description**: SMTP Server for sending and receiving email messages. This server is responsible for handling email communication.
- **Port 8025**:
@@ -304,7 +304,7 @@ cp .env.example .env
</CodeGroup>
</Col>
4. Generate & set some secret values mandatory for the ENCRYPTION_KEY & NEXTAUTH_SECRET in the .env file. You can use the following command to generate the random string of required length:
4. Generate & set some secret values mandatory for the `ENCRYPTION_KEY` & `NEXTAUTH_SECRET` in the .env file. You can use the following command to generate the random string of required length:
<Col>
<CodeGroup title="Set value of ENCRYPTION_KEY">
@@ -330,8 +330,8 @@ pnpm go
</Col>
This starts the Formbricks main app (plus all its dependencies) as well as the following services using Docker:
- a `postgres` container for hosting your database,
- a `mailhog` container that acts as a mock SMTP server and shows received mails in a web UI (forwarded to your host's `localhost:8025`)
- A `postgres` container for hosting your database,
- A `mailhog` container that acts as a mock SMTP server and shows received mails in a web UI (forwarded to your host's `localhost:8025`)
- Demo App at [http://localhost:3002](http://localhost:3002)
- Landing Page at [http://localhost:3001](http://localhost:3001)
@@ -361,4 +361,4 @@ pnpm build
---
Still cant figure it out? Join our [Discord](https://discord.com/invite/3YFcABF2Ts)!
Cant figure it out? Join our [Discord](https://discord.com/invite/3YFcABF2Ts)!

View File

@@ -46,8 +46,8 @@ All you need to do is copy a `<script>` tag to your HTML head, and thats abou
```html {{ title: 'index.html' }}
<!-- START Formbricks Surveys -->
<script type="text/javascript">
!function(){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src="https://unpkg.com/@formbricks/js@^1.4.0/dist/index.umd.js";var e=document.getElementsByTagName("script")[0];e.parentNode.insertBefore(t,e),setTimeout(function(){window.formbricks.init({environmentId: "<your-environment-id>", apiHost: "<api-host>"})},500)}();
</script>
!function(){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src="https://unpkg.com/@formbricks/js@^1.6.0/dist/index.umd.js";var e=document.getElementsByTagName("script")[0];e.parentNode.insertBefore(t,e),setTimeout(function(){window.formbricks.init({environmentId: "<your-environment-id>", apiHost: "<api-host>"})},500)}();
</script>
<!-- END Formbricks Surveys -->
```
</CodeGroup>
@@ -388,6 +388,55 @@ To this:
className="max-w-full rounded-lg sm:max-w-3xl"
/>
## Debugging Formbricks Integration
Enabling Formbricks debug mode in your browser is a useful troubleshooting step for identifying and resolving complex issues. This section outlines how to activate debug mode, covers common use cases, and provides insights into specific debug log messages.
### Activate Debug Mode
To activate Formbricks debug mode:
1. **In Your Integration Code:**
- Locate the initialization code for Formbricks in your application (HTML, ReactJS, NextJS, VueJS).
- Set the `debug` option to `true` when initializing Formbricks.
2. **View Debug Logs:**
- Open your browser's developer tools by pressing `F12` or right-clicking and selecting "Inspect."
- Navigate to the "Console" tab to view Formbricks debugging information.
**How to Open Browser Console:**
- **Google Chrome:** Press `F12` or right-click, select "Inspect," and go to the "Console" tab.
- **Firefox:** Press `F12` or right-click, select "Inspect Element," and go to the "Console" tab.
- **Safari:** Press `Option + Command + C` to open the developer tools and navigate to the "Console" tab.
- **Edge:** Press `F12` or right-click, select "Inspect Element," and go to the "Console" tab.
3. **Via URL Parameter:**
- For quick activation, add `?formbricksDebug=true` to your application's URL.
This parameter will enable debugging for the current session.
### Common Use Cases
Debug mode is beneficial for scenarios such as:
- Verifying Formbricks functionality.
- Identifying integration issues.
- Troubleshooting unexpected behavior.
### Debug Log Messages
Specific debug log messages may provide insights into:
- API calls and responses.
- Event tracking and form interactions.
- Integration errors.
**Note:** Disable debugging in production to prevent unnecessary logs and improve performance.
## Overwrite CSS Styles for In-App Surveys
You can overwrite the default CSS styles for the in-app surveys by adding the following CSS to your global CSS file (eg. `globals.css`):

View File

@@ -0,0 +1,73 @@
export const metadata = {
title: "Using Actions in Formbricks | Fine-tuning User Moments",
description:
"Dive deep into how actions in Formbricks help products and teams to engage users at precise moments in their journey. Discover the power of actions, from coding to no-code setups, to refine user targeting and generate richer, more detailed user insights.",
};
#### In-App Surveys
# Actions
You want to understand what your users think and feel during specific moments in the user journey. To be able to ask at exactly the right point in time, you need actions.
## How do Actions work?
Actions are a little notification sent from your application to Formbricks. When a predefined action happens in your app, the Formbricks widget notices. This action can then trigger a survey to be shown to the user and is stored in the database.
You decide which actions are sent either in your [Code](#code-actions) or by setting up a [No-Code](#no-code-actions) action within Formbricks.
### Why are actions useful?
Actions help you to display your surveys at the right time. Later on, you will be able to segment your users based on the actions they have triggered in the past. This way, you can create much more granular user segments, e.g. only target users that already have used a specific feature.
## No-Code Actions
No-Code actions can be set up within Formbricks with just a few clicks. There are three types of No-Code actions:
1. **Page URL Action**
The page URL action is triggered, when a user visits a specific page in your application. There are several match conditions:
- `exactMatch`: The URL should exactly match the provided string.
- `contains`: The URL should contain the specified string as a substring.
- `startsWith`: The URL should start with the specified string.
- `endsWith`: The URL should end with the specified string.
- `notMatch`: The URL should not match the specified condition.
- `notContains`: The URL should not contain the specified string as a substring.
2. **innerText Action**
The innerText action checks if the `innerText` of a clicked HTML element matches a specific text, e.g. the label of a button. Display a survey on any button click!
3. **CSS Selector Action**
The CSS Selector action checks if the provided CSS selector matches the selector of a clicked HTML element. The CSS selector can be a class, id or any other CSS selector within your website. Display a survey on any element click!
## Code Actions
Actions can also be set in the codebase to trigger surveys. Please add the code action first in the Formbricks web interface to be able to configure your surveys to use this action.
After that you can fire an action using `formbricks.track()`
<Col>
<CodeGroup title="Track an action">
```javascript
formbricks.track("Action Name");
```
</CodeGroup>
</Col>
Here is an example of how to fire an action when a user clicks a button:
<Col>
<CodeGroup title="Track Button Click">
```javascript
const handleClick = () => {
formbricks.track("Button Clicked");
};
return <button onClick={handleClick}>Click Me</button>;
```
</CodeGroup>
</Col>

View File

@@ -1,18 +1,28 @@
export const metadata = {
title: "User Identification in Formbricks | Enhancing Survey Feedback",
title: "Understanding User Attributes in Formbricks Surveys",
description:
"A comprehensive guide on identifying users in Formbricks without compromising privacy. Learn how to set User ID, email, and custom attributes to optimize survey targeting, recontact users, and control survey intervals, all while respecting user anonymity.",
"Dive into the importance of attributes in surveys. Learn how key-value pairs can significantly improve survey targeting, enhance feedback quality, and guide data-driven decisions with Formbricks.",
};
#### Attributes
#### In-App Surveys
# Identifying Users
# Attributes
At Formbricks, we value user privacy. By default, Formbricks doesn't collect or store any personal information from your users. However, we understand that it can be helpful for you to know which user submitted the feedback and also functionality like recontacting users and controlling the waiting period between surveys requires identifying the users. That's why we provide a way for you to share existing user data from your app, so you can view it in our dashboard.
Surveying your user base without segmentation leads to weak results and survey fatigue. Attributes help you segment your users into groups.
If you would like to use the User Identification feature of Formbricks, target surveys to specific user segments and see more information about the user who responded to a survey, you can identify users by setting a User ID, email, and custom attributes. This guide will walk you through how to do that.
## How do Attributes work?
## Setting User ID
Attributes are **key-value pairs** that you can set for each person individually.
Attributes are sent from your application to Formbricks and are associated with the current user. We store it in our database and allow you to use it the next time you create a survey. They help show surveys to the right group of people.
<Note>
At Formbricks, we value user privacy. By default, Formbricks doesn't collect or store any personal information from your users.
</Note>
## Identifying Users
To use the User Identification feature of Formbricks, target surveys to specific user segments and see more information about the user who responded to a survey, you can identify users by setting a User ID, email, and custom attributes. Below is how to do that.
### Setting User ID
To enable the User identification feature you need to set the `userId` in the init() call of Formbricks. Only when the `userId` is set the person will be visible in the Formbricks dashboard. The `userId` can be any string and it's best to use the default identifier you use in your app (e.g. unique id from database or the email address if it's unique) but you can also anonymize these as long as they are unique for every user.
@@ -30,7 +40,7 @@ formbricks.init({
</CodeGroup>
</Col>
## Enhanced Initialization with User Attributes
### Enhanced Initialization with User Attributes
In addition to setting the `userId`, Formbricks allows you to set user attributes right at the initialization. This ensures that your user data is seamlessly integrated from the start. Here's how you can include user attributes in the `init()` function:
@@ -52,7 +62,7 @@ formbricks.init({
</CodeGroup>
</Col>
## Setting User Email
### Setting User Email
The `userId` is the main identifier used in Formbricks and user identification is only enabled when it is set. In addition to the userId you can also set attributes that describes the user better. The email address can be set using the setEmail function:
@@ -65,7 +75,8 @@ formbricks.setEmail("user@example.com");
</CodeGroup>
</Col>
### Setting Custom User Attributes
## Setting Custom User Attributes
You can use the setAttribute function to set any custom attribute for the user (e.g. name, plan, etc.):
@@ -78,6 +89,20 @@ formbricks.setAttribute("Plan", "free");
</CodeGroup>
</Col>
Generally speaking, the setAttribute function works like this:
<Col>
<CodeGroup title="Setting Custom Attributes">
```javascript
formbricks.setAttribute("attribute_key", "attribute_value");
```
</CodeGroup>
</Col>
Where `attributeName` is the name of the attribute you want to set, and `attributeValue` is the value of the attribute you want to set.
### Logging Out Users
When a user logs out of your webpage, make sure to log them out of Formbricks as well. This will prevent new activity from being associated with an incorrect user. Use the logout function:

View File

@@ -0,0 +1,86 @@
export const metadata = {
title: "Identifying Users in Formbricks In-App Surveys",
description:
"Dive into the importance of user identification in surveys. Boost your survey response rates and target the right users with Formbricks.",
};
#### In-App Surveys
# User Identification
User Identification helps you to not only segment your users but also to see more information about the user who responded to a survey. This helps you to target surveys to specific user segments and see more information about the user who responded to a survey.
### Understanding Identified vs Unidentified Users
In Formbricks, understanding the distinction between identified and unidentified users is crucial for effective survey segmentation and targeted feedback collection.
| Feature | Unidentified Users | Identified Users |
| -------------------------------------------------------- | ------------------ | ---------------- |
| Show surveys based on **trigger** actions | ✅ | ✅ |
| Set **recontact details** to avoid survey fatique | ✅ | ✅ |
| Target a subset of users using **attributes & segments** | ❌ | ✅ |
| Collect **user information** in Formbricks | ❌ | ✅ |
| Track **custom attributes** | ❌ | ✅ |
| Counts towards your **monthly tacked user (MTU)** limit | ❌ | ✅ |
| Recommended for **public-facing websites** | ✅ | ❌ |
| Recommended for **web apps after login** | ❌ | ✅ |
## Unidentified Users
Unidentified users are those without a specific userId set. Surveys can still be presented to these users based on trigger actions, but without the granularity of user-specific targeting.
This method is recommended for public-facing websites where users are not required to log in.
<Col>
<CodeGroup title="Initialization without a user ID">
```javascript
formbricks.init({
environmentId: "<environment-id>",
apiHost: "<api-host>",
});
```
</CodeGroup>
</Col>
## Identified Users
Identified users are those for whom specific information has been set, notably the userId. This identification allows for more precise targeting of surveys and a deeper understanding of the feedback provided. When enabled, all information specified by you and all actions are sent to Formbricks.
This method is recommended for applications where users are required to log in and will often return.
**Setting the User ID:**
To identify a user, set the `userId` in the Formbricks initialization call. The userId should be a unique string, such as a database ID or an email address. This is essential for the user to be visible on the Formbricks dashboard.
<Col>
<CodeGroup title="Initialization with a user ID">
```javascript
formbricks.init({
environmentId: "<environment-id>",
apiHost: "<api-host>",
userId: "<user_id>",
});
```
</CodeGroup>
</Col>
**Logging Out Users:**
When a user logs out of your application, ensure they are also logged out of Formbricks. This prevents the association of their activities with the wrong user profile.
<Col>
<CodeGroup title="Logging out User">
```javascript
formbricks.logout();
```
</CodeGroup>
</Col>
<Note>
To set other custom attributes for a user, view our <a href="/docs/in-app-surveys/attributes">Attributes</a>{" "}
documentation.
</Note>

View File

@@ -123,6 +123,7 @@ We will first create a Google Cloud Project and then enable the Google Sheets AP
- `GOOGLE_SHEETS_CLIENT_ID` - Client ID
- `GOOGLE_SHEETS_CLIENT_SECRET` - Client Secret
16. Also use the **same Authorized redirect URI** in the `GOOGLE_SHEETS_REDIRECT_URL` environment variable.
17. One last that we need to do is to **enable the Google Drive API** for the project. For that, go to the "**APIs & Services**" section and click on the "**Enable APIs and Services**" button and search for "**Google Drive API**" and enable it.
### By now, your environment variables should include the below ones as well:

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -0,0 +1,97 @@
import Image from "next/image";
import FilledHiddenFields from "./filled-hidden-fields.webp";
import HiddenFieldResponses from "./hidden-field-responses.webp";
import HiddenFields from "./hidden-fields.webp";
import InputHiddenFields from "./input-hidden-fields.webp";
import SettingsPage from "./settings.webp";
export const metadata = {
title: "Hidden Fields",
description: "Add hidden fields to your surveys to capture additional data without requiring user inputs!",
};
#### Link Surveys
# Hidden Fields
Hidden fields are a powerful feature in Formbricks that allows you to add data to a submission without asking the user to type it in. This feature is especially useful when you already have information about a user that you want to use in the analysis of the survey results (e.g. `payment plan` or `email`)
## How to Add Hidden Fields
### Enable them in the Survey Builder
1. Edit the survey you want to add hidden fields to & open it's settings, make sure it's selected as a **Link Survey**.
<Image
src={SettingsPage}
alt="Select the Survey Type as Link Survey"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
2. Switch to the Questions tab and scroll down to the bottom of the page. You will see a section called **Hidden Fields**. Make sure to enable it by toggling the switch.
<Image
src={HiddenFields}
alt="Enable Hidden Fields"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
3. Now click on it to add a new hidden field ID. You can add as many hidden fields as you want.
<Image
src={InputHiddenFields}
alt="Add Hidden Fields"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
<Image
src={FilledHiddenFields}
alt="Filled Hidden Fields"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
### Set Single Hidden Field
<Col>
<CodeGroup title="Example Screen from which the User filled it">
```sh
https://formbricks.com/clin3dxja02k8l80hpwmx4bjy?screen=pricing
```
</CodeGroup>
</Col>
### Set Multiple Hidden Fields
<Col>
<CodeGroup title="Example Screen from which the User filled it">
```sh
https://formbricks.com/clin3dxja02k8l80hpwmx4bjy?screen=landing_page&job=Founder
```
</CodeGroup>
</Col>
## View Hidden Fields in Responses
These hidden fields will now be visible in the responses tab just like other fields in the Summary as well as the Response Cards, and you can use them to filter and analyze your responses.
<Image
src={HiddenFieldResponses}
alt="Hidden Field Responses"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
## Use Cases
- **Tracking Source**: You can add a hidden field to track the source of the survey. For a detailed guide on Source Tracking, check out the [Source Tracking](/docs/link-surveys/source-tracking) guide.
- **User Metadata**: You can add hidden fields to capture user metadata such as user ID, email, or any other user-specific information.
- **Survey Metadata**: You can add hidden fields to capture other metadata, e.g. the screen from which the survey was filled, or any other app specific information.

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,88 @@
import Image from "next/image";
import HomePage from "./home-page.webp";
import SurveyQuestions from "./survey-questions.webp";
import SurveySettings from "./survey-settings.webp";
import SurveyResponseOptions from "./survey-response-options.webp";
import SurveyPublished from "./survey-published.webp";
export const metadata = {
title: "Formbricks Quickstart Guide: Link Surveys Made Easier & Faster",
description:
"Formbricks is the easiest way to create and manage link surveys. This quickstart guide will show you how to create your first link survey in under 5 minutes.",
};
#### Getting Started
# Quickstart
Link Surveys make it easy for your users to give you feedback. They are a great way to get feedback from your users, without interrupting their workflow. This quickstart guide will show you how to create your first link survey in under 5 minutes.
## Create a free Formbricks Cloud account
While you can [self-host](/docs/self-hosting/deployment) Formbricks, but the quickest and easiest way to get started is with the free Cloud plan. Just [sign up here](https://app.formbricks.com/auth/signup) and click through the onboarding, until youre here:
<Image
src={HomePage}
alt="Choose a link survey template"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl "
/>
Choose one of the pre-created templates to get started. Well choose the **Product Market Fit** template for this quickstart guide.
## Create your first survey
On clicking the template, youll be forwarded to the survey editor. Here you can edit the survey questions and settings. For the sake of simplicity, we'll keep the questions as they are and move to the survey settings.
<Image
src={SurveyQuestions}
alt="Survey Editor opens up in the Formbricks App"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
Click on the **Settings** tab to edit the survey settings.
## Configure your survey settings
Formbricks packs a lot of useful functionality out of the box. You can:
- Close the survey on a specidic date
- After a number of response
- Redirect users to a URL after they completed the survey
- Protect survey with a Pin
- ... and much more!
<Image
src={SurveyResponseOptions}
alt="Survey response configuration for link survey"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
## Style your survey
Style your survey to your need. You can keep it simplistic or use animated backgrounds. You can change the main color and soon you'll be able to fully control the appearance of the survey.
<Image
src={SurveySettings}
alt="UI & View configuration for link survey"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
## Publish your survey
Once youre happy with the survey settings, hit **Publish** and youll be forwarded to the Summary Page. This is where youll find the responses to this survey.
<Image
src={SurveyPublished}
alt="Survey published successfully and received link to share with users"
quality="100"
className="max-w-full rounded-lg sm:max-w-3xl"
/>
## Share your survey
Congratulations! Your survey is now published and ready to be shared with your users. You can share the survey link via email, SMS, or any other channel.

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -10,7 +10,7 @@ export const metadata = {
Quickly set up and start using Formbricks without getting into the technicalities of the build process. You'll be using an image that we've already built for you. The pre-built image is ready-to-run, and it only requires minimal configuration on your part. This approach is perfect for getting a functional instance of Formbricks up and running with minimal hassle. It's as easy as downloading the Docker image and firing up the container.
This is ideal for those who are testing Formbricks or want to run it with minimal to no modifications. For this we use the [public Docker image](https://hub.docker.com/r/formbricks/formbricks) and a simple docker-compose file.
This is ideal for those who are testing Formbricks or want to run it with minimal to no modifications. For this we use the [public Docker image](https://github.com/formbricks/formbricks/pkgs/container/formbricks) and a simple docker-compose file.
### Requirements
@@ -201,69 +201,10 @@ formbricks-quickstart-formbricks-1 | Listening on port 3000 url: http://<random
You can close the logs again with `CTRL + C`.
<Note>
## Customizing the Build Time variables
## Customizing environment variables
To edit any of the variables that start with `NEXT_PUBLIC_`, you need to rebuild the Formbricks Docker Image!
To edit any of the available environment variables, check out our [Configure](/docs/self-hosting/external-auth-providers) section!
</Note>
## Important Run-time Variables
These variables can be provided at the runtime i.e. in your docker-compose file.
| Variable | Description | Required | Default |
| --------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------------- |
| WEBAPP_URL | Base URL of the site. | required | `http://localhost:3000` |
| DATABASE_URL | Database URL with credentials. | required | `postgresql://postgres:postgres@postgres:5432/formbricks?schema=public` |
| NEXTAUTH_SECRET | Secret for NextAuth, used for session signing and encryption. | required | (Generated by the user) |
| NEXTAUTH_URL | Location of the auth server. By default, this is the Formbricks docker instance itself. | required | `http://localhost:3000` |
| PRIVACY_URL | URL for privacy policy. | optional | |
| TERMS_URL | URL for terms of service. | optional | |
| IMPRINT_URL | URL for imprint. | optional | |
| SIGNUP_DISABLED | Disables the ability for new users to create an account if set to `1`. | optional | |
| PASSWORD_RESET_DISABLED | Disables password reset functionality if set to `1`. | optional | |
| EMAIL_VERIFICATION_DISABLED | Disables email verification if set to `1`. | optional | |
| INVITE_DISABLED | Disables the ability for invited users to create an account if set to `1`. | optional | |
| MAIL_FROM | Email address to send emails from. | optional (required if email services are to be enabled) | |
| SMTP_HOST | Host URL of your SMTP server. | optional (required if email services are to be enabled) | |
| SMTP_PORT | Host Port of your SMTP server. | optional (required if email services are to be enabled) | |
| SMTP_USER | Username for your SMTP Server. | optional (required if email services are to be enabled) | |
| SMTP_PASSWORD | Password for your SMTP Server. | optional (required if email services are to be enabled) | |
| SMTP_SECURE_ENABLED | SMTP secure connection. For using TLS, set to `1` else to `0`. | optional (required if email services are to be enabled) | |
| GITHUB_AUTH_ENABLED | Enables GitHub login if set to `1`. | optional | |
| GOOGLE_AUTH_ENABLED | Enables Google login if set to `1`. | optional | |
| GITHUB_ID | Client ID for GitHub. | optional (required if GitHub auth is enabled) | |
| GITHUB_SECRET | Secret for GitHub. | optional (required if GitHub auth is enabled) | |
| GOOGLE_CLIENT_ID | Client ID for Google. | optional (required if Google auth is enabled) | |
| GOOGLE_CLIENT_SECRET | Secret for Google. | optional (required if Google auth is enabled) | |
| CRON_SECRET | API Secret for running cron jobs. | optional | |
| STRIPE_SECRET_KEY | Secret key for Stripe integration. | optional | |
| STRIPE_WEBHOOK_SECRET | Webhook secret for Stripe integration. | optional | |
| TELEMETRY_DISABLED | Disables telemetry if set to `1`. | optional | |
| INSTANCE_ID | Instance ID for Formbricks Cloud to be sent to Telemetry. | optional | |
| INTERNAL_SECRET | Internal Secret (Currently we overwrite the value with a random value). | optional | |
| DEFAULT_BRAND_COLOR | Default brand color for your app (Can be overwritten from the UI as well). | optional | `#64748b` |
| DEFAULT_TEAM_ID | Automatically assign new users to a specific team when joining | optional | |
| DEFAULT_TEAM_ROLE | Role of the user in the default team. | optional | `admin` |
| ONBOARDING_DISABLED | Disables onboarding for new users if set to `1` | optional | |
## Build-time Variables
These variables must be provided at the time of the docker build and would require rebuilding the image.
| Variable | Description | Required | Default |
| -------------------------------------------------- | --------------------------------------------------------------- | -------- | ------- |
| NEXT_PUBLIC_FORMBRICKS_API_HOST | Host for the Formbricks API. | optional | |
| NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID | If you already have a preset environment ID of the environment. | optional | |
| NEXT_PUBLIC_FORMBRICKS_ONBOARDING_SURVEY_ID | If you already have an onboarding survey ID to show new users. | optional | |
| NEXT_PUBLIC_POSTHOG_API_KEY | API key for PostHog analytics. | optional | |
| NEXT_PUBLIC_POSTHOG_API_HOST | Host for PostHog analytics. | optional | |
| NEXT_PUBLIC_SENTRY_DSN | DSN for Sentry error tracking. | optional | |
| NEXT_PUBLIC_DOCSEARCH_APP_ID | ID of the DocSearch application. | optional | |
| NEXT_PUBLIC_DOCSEARCH_API_KEY | API key of the DocSearch application. | optional | |
| NEXT_PUBLIC_DOCSEARCH_INDEX_NAME | Name of the DocSearch index. | optional | |
| NEXT_PUBLIC_FORMBRICKS_COM_ENVIRONMENT_ID | Environment ID for Formbricks (if you already have one) | optional | |
| NEXT_PUBLIC_FORMBRICKS_COM_DOCS_FEEDBACK_SURVEY_ID | Survey ID for the feedback survey on the docs site. | optional | |
| NEXT_PUBLIC_FORMBRICKS_COM_API_HOST | Host for the Formbricks API. | optional | |
Still facing issues? [Join our Discord!](https://formbricks.com/discord) and we'd be glad to assist you!

View File

@@ -0,0 +1,26 @@
export const metadata = {
title: "Enterprise License to unlock advanced functionality",
description:
"Request a self-hosting licenses to unlock advanced enterprise functionality",
};
#### Self-Hosting
# Enterprise License Request (Beta)
We're handing out free enterprise license keys during our beta.
Additional to the AGPL licensed Formbricks core, the Formbricks repository contains code licensed under an [Enterprise license](https://github.com/formbricks/formbricks/blob/main/packages/ee/LICENSE). This additional functionality is not part of the AGPLv3 licensed Formbricks core and is designed to meet the needs of larger teams and enterprises. This advanced functionality is already included in the Docker images, but you need an [Enterprise License Key](https://formbricks.com/docs/self-hosting/license) to unlock it.
**Please note:** Sooner than later we will introduce a enterprise license pricing. For a free beta key, fill out this form:
<div style={{ position: 'relative', height: '100vh', maxHeight: '100vh', overflow: 'auto', borderRadius:'12px' }}>
<iframe
src="https://app.formbricks.com/s/clrf4z8zg1u3912250j7shqb5"
style={{ position: 'absolute', left: 0, top: 0, width: '100%', height: '100%', border: 0 }}
>
</iframe>
</div>
**Cant figure it out?**: [Join our Discord!](https://formbricks.com/discord)

View File

@@ -40,12 +40,11 @@ Integrating Google OAuth with your Formbricks instance allows users to log in us
- Ensure to specify authorized JavaScript origins and authorized redirect URIs.
<Col>
<CodeGroup title="Configuration URLs">
``` {{ title: 'Redirect & Origin URLs' }}
Authorized JavaScript origins: {WEBAPP_URL}
Authorized redirect URIs: {WEBAPP_URL}/api/auth/callback/google
```
</CodeGroup>
<CodeGroup title="Configuration URLs">
``` {{ title: "Redirect & Origin URLs" }}
Authorized JavaScript origins: {WEBAPP_URL}
Authorized redirect URIs: {WEBAPP_URL}/api/auth/callback/google ```
</CodeGroup>
</Col>
5. **Update Environment Variables in Docker**:
@@ -58,14 +57,12 @@ Authorized redirect URIs: {WEBAPP_URL}/api/auth/callback/google
```sh {{ title: 'Shell commands' }}
docker exec -it container_id /bin/bash
export GOOGLE_AUTH_ENABLED=1
export GOOGLE_CLIENT_ID=your-client-id-here
export GOOGLE_CLIENT_SECRET=your-client-secret-here
exit
```
```sh {{ title: 'env file' }}
GOOGLE_AUTH_ENABLED=1
GOOGLE_CLIENT_ID=your-client-id-here
GOOGLE_CLIENT_SECRET=your-client-secret-here
```
@@ -78,3 +75,103 @@ GOOGLE_CLIENT_SECRET=your-client-secret-here
- Once the environment variables have been updated, it's crucial to restart your Docker containers to apply the changes. This ensures that your Formbricks instance can utilize the new Google OAuth configuration for user authentication. Here's how you can do it:
- Navigate to your Docker setup directory where your `docker-compose.yml` file is located.
- Run the following command to bring down your current Docker containers and then bring them back up with the updated environment configuration:
## OpenID Integration
Integrating your own OIDC (OpenID Connect) instance with your Formbricks instance allows users to log in using their OIDC credentials, ensuring a secure and streamlined user experience. Please follow the steps below to set up OIDC for your Formbricks instance.
1. Configure your OIDC provider & get the following variables:
- `OIDC_CLIENT_ID`
- `OIDC_CLIENT_SECRET`
- `OIDC_ISSUER`
- `OIDC_SIGNING_ALGORITHM`
<Note>
Make sure the Redirect URI for your OIDC Client is set to `{WEBAPP_URL}/api/auth/callback/openid`.
</Note>
2. Update these environment variables in your `docker-compose.yml` or pass it directly to the running container.
An example configuration for a FusionAuth OpenID Connect in Formbricks would look like:
<Col>
<CodeGroup title="Formbricks Env for FusionAuth OIDC">
```yml {{ title: '.env' }}
OIDC_CLIENT_ID=59cada54-56d4-4aa8-a5e7-5823bbe0e5b7
OIDC_CLIENT_SECRET=4f4dwP0ZoOAqMW8fM9290A7uIS3E8Xg29xe1umhlB_s
OIDC_ISSUER=http://localhost:9011
OIDC_DISPLAY_NAME=FusionAuth
OIDC_SIGNING_ALGORITHM=HS256
```
</CodeGroup>
</Col>
3. Set an environment variable `OIDC_DISPLAY_NAME` to the display name of your OIDC provider.
4. Restart your Formbricks instance.
5. You're all set! Users can now signup & log in using their OIDC credentials.
## Important Run-time Variables
These variables can be provided at the runtime i.e. in your docker-compose file.
| Variable | Description | Required | Default |
| --------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----------------------- |
| WEBAPP_URL | Base URL of the site. | required | `http://localhost:3000` |
| DATABASE_URL | Database URL with credentials. | required | |
| NEXTAUTH_SECRET | Secret for NextAuth, used for session signing and encryption. | required | (Generated by the user) |
| ENCRYPTION_KEY | Secret for used by Formbricks for data encryption | required | (Generated by the user) |
| NEXTAUTH_URL | Location of the auth server. By default, this is the Formbricks docker instance itself. | required | `http://localhost:3000` |
| S3_ACCESS_KEY | Access key for S3. | optional (required if S3 is enabled) | |
| S3_SECRET_KEY | Secret key for S3. | optional (required if S3 is enabled) | |
| S3_REGION | Region for S3. | optional (required if S3 is enabled) | |
| S3_BUCKET | Bucket name for S3. | optional (required if S3 is enabled) | |
| S3_ENDPOINT | Endpoint for S3. | optional (required if S3 is enabled) | |
| PRIVACY_URL | URL for privacy policy. | optional | |
| TERMS_URL | URL for terms of service. | optional | |
| IMPRINT_URL | URL for imprint. | optional | |
| SIGNUP_DISABLED | Disables the ability for new users to create an account if set to `1`. | optional | |
| EMAIL_AUTH_DISABLED | Disables the ability for users to signup or login via email and password if set to `1`. | optional | |
| PASSWORD_RESET_DISABLED | Disables password reset functionality if set to `1`. | optional | |
| EMAIL_VERIFICATION_DISABLED | Disables email verification if set to `1`. | optional | |
| RATE_LIMITING_DISABLED | Disables rate limiting if set to `1`. | optional | |
| INVITE_DISABLED | Disables the ability for invited users to create an account if set to `1`. | optional | |
| MAIL_FROM | Email address to send emails from. | optional (required if email services are to be enabled) | |
| SMTP_HOST | Host URL of your SMTP server. | optional (required if email services are to be enabled) | |
| SMTP_PORT | Host Port of your SMTP server. | optional (required if email services are to be enabled) | |
| SMTP_USER | Username for your SMTP Server. | optional (required if email services are to be enabled) | |
| SMTP_PASSWORD | Password for your SMTP Server. | optional (required if email services are to be enabled) | |
| SMTP_SECURE_ENABLED | SMTP secure connection. For using TLS, set to `1` else to `0`. | optional (required if email services are to be enabled) | |
| GITHUB_ID | Client ID for GitHub. | optional (required if GitHub auth is enabled) | |
| GITHUB_SECRET | Secret for GitHub. | optional (required if GitHub auth is enabled) | |
| GOOGLE_CLIENT_ID | Client ID for Google. | optional (required if Google auth is enabled) | |
| GOOGLE_CLIENT_SECRET | Secret for Google. | optional (required if Google auth is enabled) | |
| CRON_SECRET | API Secret for running cron jobs. | optional | |
| STRIPE_SECRET_KEY | Secret key for Stripe integration. | optional | |
| STRIPE_WEBHOOK_SECRET | Webhook secret for Stripe integration. | optional | |
| TELEMETRY_DISABLED | Disables telemetry if set to `1`. | optional | |
| INSTANCE_ID | Instance ID for Formbricks Cloud to be sent to Telemetry. | optional | |
| INTERNAL_SECRET | Internal Secret (Currently we overwrite the value with a random value). | optional | |
| DEFAULT_BRAND_COLOR | Default brand color for your app (Can be overwritten from the UI as well). | optional | `#64748b` |
| DEFAULT_TEAM_ID | Automatically assign new users to a specific team when joining | optional | |
| DEFAULT_TEAM_ROLE | Role of the user in the default team. | optional | `admin` |
| ONBOARDING_DISABLED | Disables onboarding for new users if set to `1` | optional | |
| OIDC_DISPLAY_NAME | Display name for Custom OpenID Connect Provider | optional | |
| OIDC_CLIENT_ID | Client ID for Custom OpenID Connect Provider | optional (required if OIDC auth is enabled) | |
| OIDC_CLIENT_SECRET | Secret for Custom OpenID Connect Provider | optional (required if OIDC auth is enabled) | |
| OIDC_ISSUER | Issuer URL for Custom OpenID Connect Provider (should have `.well-known` configured at this) | optional (required if OIDC auth is enabled) | |
| OIDC_SIGNING_ALGORITHM | Signing Algorithm for Custom OpenID Connect Provider | optional | `RS256` |
## Build-time Variables
These variables must be provided at the time of the docker build and would require rebuilding the image.
| Variable | Description | Required | Default |
| ------------------------------------- | ----------------------------------------------------- | -------- | ------- |
| NEXT_PUBLIC_FORMBRICKS_API_HOST | Host for the Formbricks API to use inside Formbricks. | optional | |
| NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID | Formbricks environment ID for use inside Formbricks. | optional | |
| NEXT_PUBLIC_POSTHOG_API_KEY | API key to use PostHog analytics inside Formbricks. | optional | |
| NEXT_PUBLIC_POSTHOG_API_HOST | Host to use PostHog analytics inside Formbricks. | optional | |
| NEXT_PUBLIC_SENTRY_DSN | DSN for Sentry error tracking inside Formbricks. | optional | |
Still facing issues? [Join our Discord!](https://formbricks.com/discord) and we'd be glad to assist you!

View File

@@ -0,0 +1,27 @@
export const metadata = {
title: "About the Formbricks Open-Source License",
description:
"The Formbricks core is available under the AGPLv3 license",
};
#### Self-Hosting
# License
## The AGPL Formbricks Core
The Formbricks core application is licensed under the [AGPLv3 Open Source License](https://github.com/formbricks/formbricks/blob/main/LICENSE). The core application is fully functional and includes everything you need to design & run link surveys, website surveys and in-app surveys. You can use the software for free for personal and commercial use. You're also allowed to create and distribute modified versions as long as you document the changes you make incl. date. The AGPL license requires you to publish your modified version under the AGPLv3 license as well.
## The Enterprise Edition
Additional to the AGPL licensed Formbricks core, this repository contains code licensed under an Enterprise license. The [code](https://github.com/formbricks/formbricks/tree/main/packages/ee) and [license](https://github.com/formbricks/formbricks/blob/main/packages/ee/LICENSE) for the enterprise functionality can be found in the `/packages/ee` folder of this repository. This additional functionality is not part of the AGPLv3 licensed Formbricks core and is designed to meet the needs of larger teams and enterprises. This advanced functionality is already included in the Docker images, but you need an [Enterprise License Key](https://formbricks.com/docs/self-hosting/enterprise) to unlock it.
## White-Labeling Formbricks and Other Licensing Needs
If you have other licensing requirements such as White-Labeling please [send us an email](mailto:hola@formbricks.com).
## Why charge for Enterprise Features?
The Enterprise Edition and White-Label Licenses allow us to fund the development of Formbricks sustainably. It guarantees that the open-source surveying infrastructure we're building will be around for decades to come.
**Having more questions?**: [Join our Discord!](https://formbricks.com/discord)

View File

@@ -8,16 +8,101 @@ export const metadata = {
# Migration Guide
## v1.1 -> v1.2
## v1.6
Formbricks v1.6 comes with a big new features like Advanced Targeting & Segmentation of your end-users along with on-the-fly triggers for surveys and a ton of stability improvements & features. This also involves a few changes in our environment variables. This guide will help you migrate your existing Formbricks instance to v1.6 without any hassles or build errors.
<Note>
This upgrade requires a **data migration**. Please make sure to backup your database before proceeding with
the upgrade. Follow the below steps thoroughly to upgrade your Formbricks instance to v1.6.
</Note>
### Steps to Migrate
This guide is for users who are self-hosting Formbricks using our one-click setup. If you are using a different setup, you might adjust the commands accordingly.
To run all these steps, please navigate to the `formbricks` folder where your `docker-compose.yml` file is located.
1. **Backup your Database**: This is a crucial step. Please make sure to backup your database before proceeding with the upgrade. You can use the following command to backup your database:
<Col>
<CodeGroup title="Backup Postgres">
```bash
docker exec formbricks-quickstart-postgres-1 pg_dump -U postgres -d formbricks > formbricks_pre_v1.6_$(date +%Y%m%d_%H%M%S).sql
```
</CodeGroup>
</Col>
2. Stop the running Formbricks instance & remove the related containers:
<Col>
<CodeGroup title="Stop the containers">
```bash
docker-compose down
```
</CodeGroup>
</Col>
3. Restarting the containers will automatically pull the latest version of Formbricks:
<Col>
<CodeGroup title="Restart the containers">
```bash
docker-compose up -d
```
</CodeGroup>
</Col>
4. Now let's migrate the data to the latest schema:
<Note>To find your Docker Network name for your Postgres Database, find it using `docker network ps`</Note>
<Col>
<CodeGroup title="Migrate the data">
```bash
docker run --rm \
--network=formbricks_default \
-e DATABASE_URL="postgresql://postgres:postgres@postgres:5432/formbricks?schema=public" \
-e UPGRADE_TO_VERSION="v1.6" \
ghcr.io/formbricks/data-migrations:v1.6
```
</CodeGroup>
</Col>
The above command will migrate your data to the latest schema. This is a crucial step to migrate your existing data to the new structure. Only if the script runs successful, changes are made to the database. The script can safely run multiple times.
5. That's it! Once the migration is complete, you can **now access your Formbricks instance** at the same URL as before.
### In-App Surveys with @formbricks/js
If you are using the `@formbricks/js` package, please make sure to update it to version 1.6.0 to use the latest features and improvements.
### Deprecated Environment Variables
| Environment Variable | Comments |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GITHUB_AUTH_ENABLED | Was used to enable GitHub OAuth, but from v1.6, you can just set the `GITHUB_ID` and `GITHUB_SECRET` environment variables. |
| GOOGLE_AUTH_ENABLED | Was used to enable Google OAuth, but from v1.6, you can just set the `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` environment variables. |
| AZUREAD_AUTH_ENABLED | Was used to enable AzureAD OAuth, but from v1.6, you can just set the `AZUREAD_CLIENT_ID`, `AZUREAD_CLIENT_SECRET` & `AZUREAD_TENANT_ID` environment variables. |
## v1.2
Formbricks v1.2 ships a lot of features targeting our Link Surveys. We have also improved our security posture to be as robust as ever. However, it also comes with a few breaking changes specifically with the environment variables. This guide will help you migrate your existing Formbricks instance to v1.2 without any hassles or build errors.
### New Environment Variables
| Environment Variable | Required | Recommended Generation | Comments |
| -------------------- | -------- | ------------------------------ | ----------------------------------------------------------- |
| ENCRYPTION_KEY | true | `openssl rand -hex 32` | Needed for 2 Factor Authentication |
| SHORT_URL_BASE | false | `<your-short-base-url>` | Needed if you want to enable shorter links for Link Surveys |
| Environment Variable | Required | Recommended Generation | Comments |
| -------------------- | -------- | ----------------------- | ----------------------------------------------------------- |
| ENCRYPTION_KEY | true | `openssl rand -hex 32` | Needed for 2 Factor Authentication |
| SHORT_URL_BASE | false | `<your-short-base-url>` | Needed if you want to enable shorter links for Link Surveys |
### Deprecated / Removed Environment Variables
@@ -25,7 +110,7 @@ Formbricks v1.2 ships a lot of features targeting our Link Surveys. We have also
| -------------------- | ------------------------------------------------------------------------- |
| SURVEY_BASE_URL | The WEBAPP_URL is now used to determine the survey base url in all places |
## v1.0 -> v1.1
## v1.1
Formbricks v1.1 includes a lot of new features and improvements. However, it also comes with a few breaking changes specifically with the environment variables. This guide will help you migrate your existing Formbricks instance to v1.1 without losing any data.
@@ -113,6 +198,9 @@ x-environment: &environment
# Uncomment the below and set it to 1 to disable Signups
# SIGNUP_DISABLED:
# Uncomment the below and set it to 1 to disable loging in with email
# EMAIL_AUTH_DISABLED:
# Uncomment the below and set it to 1 to disable Invites
# INVITE_DISABLED:
@@ -136,6 +224,7 @@ x-environment: &environment
# GOOGLE_CLIENT_SECRET:
```
</CodeGroup>
</Col>
Did we miss something? Are you still facing issues migrating your app? [Join our Discord!](https://formbricks.com/discord) We'd be happy to help!

View File

@@ -10,8 +10,16 @@ export const metadata = {
If you want to quickly set up a production instance of Formbricks on a server running Ubuntu, we've got you covered! This method utilizes a convenient shell script that takes care of everything, including Docker, Postgres DB, and SSL certificate configuration. The shell script will automatically install all the required dependencies and configure your server, making the process a breeze.
<Note>
This setup installs **Traefik** to work as a **reverse proxy**. This configuration is crucial for directing incoming traffic to the correct container, allowing Formbricks to be accessible from the internet securely.
Traefik is chosen for its simplicity and automatic SSL management with Let's Encrypt.
</Note>
This is the quickest way to get Formbricks up and running on an Ubuntu server. The shell script will automatically install all the required dependencies and configure your server, making the process a breeze.
If you want to run Formbricks on a different OS or have more control over the installation process, you can follow the [advanced installation guide](/docs/self-hosting/docker) with Docker.
### Requirements
Before you proceed, make sure you have the following:
@@ -29,7 +37,7 @@ Copy and paste the following command into your terminal:
<CodeGroup title="Single Command to deploy Formbricks">
```bash
curl -fsSL https://raw.githubusercontent.com/formbricks/formbricks/main/docker/production.sh -o formbricks.sh && chmod +x formbricks.sh && ./formbricks.sh install
curl -fsSL https://raw.githubusercontent.com/formbricks/formbricks/main/docker/formbricks.sh -o formbricks.sh && chmod +x formbricks.sh && ./formbricks.sh install
```
</CodeGroup>
@@ -219,18 +227,16 @@ The script will automatically stop all the Formbricks related containers, remove
## Debugging
If you encounter any issues, you can check the logs of the container with:
If you encounter any issues, you can check the logs of the containers with:
<Col>
<CodeGroup title="Check logs of the container">
```bash
cd formbricks && docker compose logs -f
./formbricks.sh logs
```
</CodeGroup>
</Col>
You can close the logs again with `CTRL + C`.
## Troubleshooting
@@ -244,4 +250,4 @@ If you encounter any issues, consider the following steps:
- **Check Formbricks Logs**: Run `cd formbricks && docker compose logs` to check the logs of the Formbricks stack.
**Still cant figure it out?**: [Join our Discord!](https://formbricks.com/discord)
**Cant figure it out?**: [Join our Discord!](https://formbricks.com/discord)

View File

@@ -5,7 +5,7 @@ import { useRouter } from "next/router";
import { Button } from "@formbricks/ui/Button";
import { FooterLogo } from "../../components/shared/Logo";
import { FooterLogo } from "../shared/Logo";
export default function HeaderLight() {
const plausible = usePlausible();

View File

@@ -1,5 +1,5 @@
import Footer from "../../components/shared/Footer";
import MetaInformation from "../../components/shared/MetaInformation";
import Footer from "../shared/Footer";
import MetaInformation from "../shared/MetaInformation";
import HeaderLight from "./HeaderLight";
interface LayoutProps {

View File

@@ -23,7 +23,7 @@ const variantStyles = {
"rounded-full bg-slate-900 py-1 px-3 text-white hover:bg-slate-700 dark:bg-teal-500 dark:text-white dark:hover:bg-teal-400",
outline:
"rounded-full py-1 px-3 text-slate-700 ring-1 ring-inset ring-slate-900/10 hover:bg-slate-900/2.5 hover:text-slate-900 dark:text-slate-400 dark:ring-white/10 dark:hover:bg-white/5 dark:hover:text-white",
text: "text-teal-500 hover:text-teal-700 dark:text-teal-400 dark:hover:text-teal-600",
text: "text-teal-500 hover:text-teal-700 dark:text-teal-400 dark:hover:text-teal-300",
};
type ButtonProps = {

View File

@@ -42,7 +42,7 @@ export function Libraries() {
<a
key={library.name}
href={library.href}
className="flex flex-row-reverse gap-6 rounded-2xl p-6 transition-all duration-100 ease-in-out hover:cursor-pointer hover:bg-slate-100/50">
className="flex flex-row-reverse gap-6 rounded-2xl p-6 transition-all duration-100 ease-in-out hover:cursor-pointer hover:bg-slate-100/50 dark:hover:bg-slate-800/50">
<div className="flex-auto">
<h3 className="text-sm font-semibold text-slate-900 dark:text-white">{library.name}</h3>
<p className="mt-1 text-sm text-slate-600 dark:text-slate-400">{library.description}</p>

View File

@@ -189,36 +189,25 @@ export const navigation: Array<NavGroup> = [
],
},
{
title: "Getting Started",
title: "In-App Surveys",
links: [
{ title: "Quickstart: In app", href: "/docs/getting-started/quickstart-in-app-survey" },
{ title: "Quickstart", href: "/docs/getting-started/quickstart-in-app-survey" },
{ title: "Framework Guides", href: "/docs/getting-started/framework-guides" },
{ title: "Troubleshooting", href: "/docs/getting-started/troubleshooting" },
],
},
{
title: "Attributes",
links: [
{ title: "Why Attributes?", href: "/docs/attributes/why" },
{ title: "Custom Attributes", href: "/docs/attributes/custom-attributes" },
{ title: "Identify users", href: "/docs/attributes/identify-users" },
],
},
{
title: "Actions",
links: [
{ title: "Why Actions?", href: "/docs/actions/why" },
{ title: "No-Code Actions", href: "/docs/actions/no-code" },
{ title: "Code Actions", href: "/docs/actions/code" },
{ title: "Identify Users", href: "/docs/in-app-surveys/user-identification" },
{ title: "Actions", href: "/docs/in-app-surveys/actions" },
{ title: "Attributes", href: "/docs/in-app-surveys/attributes" },
],
},
{
title: "Link Surveys",
links: [
{ title: "Quickstart", href: "/docs/link-surveys/quickstart" },
{ title: "Data Prefilling", href: "/docs/link-surveys/data-prefilling" },
{ title: "Identify Users", href: "/docs/link-surveys/user-identification" },
{ title: "Single Use Links", href: "/docs/link-surveys/single-use-links" },
{ title: "Source Tracking", href: "/docs/link-surveys/source-tracking" },
{ title: "Hidden Fields", href: "/docs/link-surveys/hidden-fields" },
],
},
{
@@ -231,6 +220,7 @@ export const navigation: Array<NavGroup> = [
{ title: "Feature Chaser", href: "/docs/best-practices/feature-chaser" },
{ title: "Feedback Box", href: "/docs/best-practices/feedback-box" },
{ title: "Docs Feedback", href: "/docs/best-practices/docs-feedback" },
{ title: "Improve Email Content", href: "/docs/best-practices/improve-email-content" },
],
},
{
@@ -253,6 +243,8 @@ export const navigation: Array<NavGroup> = [
{ title: "Advanced Setup", href: "/docs/self-hosting/docker" },
{ title: "Configure", href: "/docs/self-hosting/external-auth-providers" },
{ title: "Migration Guide", href: "/docs/self-hosting/migration-guide" },
{ title: "License", href: "/docs/self-hosting/license" },
{ title: "Enterprise License", href: "/docs/self-hosting/enterprise" },
],
},
{
@@ -285,6 +277,7 @@ export const navigation: Array<NavGroup> = [
{ title: "Attribute Classes", href: "/docs/api/management/attribute-classes" },
{ title: "Me", href: "/docs/api/management/me" },
{ title: "People", href: "/docs/api/management/people" },
{ title: "Responses", href: "/docs/api/management/responses" },
{ title: "Surveys", href: "/docs/api/management/surveys" },
{ title: "Webhooks", href: "/docs/api/management/webhooks" },
],

View File

@@ -1,11 +1,10 @@
/* import { cleanHtml } from "../../lib/cleanHtml"; */
import { cleanHtml } from "@formbricks/lib/cleanHtml";
import * as DOMPurify from "dompurify";
export default function HtmlBody({ htmlString, questionId }: { htmlString: string; questionId: string }) {
return (
<label
htmlFor={questionId}
className="fb-block fb-font-normal fb-leading-6 text-sm text-slate-500 dark:text-slate-300"
dangerouslySetInnerHTML={{ __html: cleanHtml(htmlString) }}></label>
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(htmlString) }}></label>
);
}

View File

@@ -50,7 +50,7 @@ export default function NPSQuestion({ question, onSubmit, lastQuestion, brandCol
selectedChoice === number
? "z-10 bg-slate-50 dark:bg-slate-500"
: "dark:bg-slate-700 dark:hover:bg-slate-500",
"relative h-10 flex-1 cursor-pointer border bg-white text-center text-sm leading-10 text-slate-900 first:rounded-l-md last:rounded-r-md hover:bg-gray-100 focus:outline-none dark:border-slate-600 dark:text-white "
"relative h-10 flex-1 cursor-pointer border bg-white text-center text-sm leading-10 text-slate-900 first:rounded-l-md last:rounded-r-md hover:bg-slate-100 focus:outline-none dark:border-slate-600 dark:text-white "
)}>
<input
type="radio"

View File

@@ -56,7 +56,7 @@ export default function RatingQuestion({
className={cn(
selectedChoice === number
? "z-10 border-slate-400 bg-slate-50"
: "bg-white hover:bg-gray-100 dark:bg-slate-700 dark:hover:bg-slate-500",
: "bg-white hover:bg-slate-100 dark:bg-slate-700 dark:hover:bg-slate-500",
"relative h-10 flex-1 cursor-pointer border border-slate-100 text-center text-sm leading-10 text-slate-800 first:rounded-l-md last:rounded-r-md focus:outline-none dark:border-slate-500 dark:text-slate-200 "
)}>
<input

View File

@@ -53,12 +53,11 @@ export default function TemplateList({ onTemplateClick, activeTemplate }: Templa
{templates
.filter((template) => selectedFilter === ALL_CATEGORY_NAME || template.category === selectedFilter)
.map((template: TTemplate) => (
<button
type="button"
<div
key={template.name}
onClick={() => {
onTemplateClick(template); // Pass the 'template' object instead of 'activeTemplate'
}}
key={template.name}
className={cn(
activeTemplate?.name === template.name && "ring-brand ring-2",
"duration-120 group relative rounded-lg bg-white p-6 shadow transition-all duration-150 hover:scale-105 dark:bg-slate-700"
@@ -71,7 +70,7 @@ export default function TemplateList({ onTemplateClick, activeTemplate }: Templa
{template.name}
</h3>
<p className="text-left text-xs text-slate-600 dark:text-slate-400">{template.description}</p>
</button>
</div>
))}
</div>
</main>

View File

@@ -14,6 +14,7 @@ import {
DashboardIcon,
DogChaserIcon,
DoorIcon,
EmailIcon,
FeedbackIcon,
GaugeSpeedFastIcon,
HeartCommentIcon,
@@ -1224,6 +1225,61 @@ export const templates: TTemplate[] = [
},
},
},
{
name: "Improve Newsletter Content",
icon: EmailIcon,
category: "Growth",
description: "Find out how your subscribers like your newsletter content.",
objectives: ["increase_conversion", "sharpen_marketing_messaging"],
preset: {
name: "Improve Newsletter Content",
questions: [
{
id: createId(),
type: TSurveyQuestionType.Rating,
logic: [
{ value: "5", condition: "equals", destination: "l2q1chqssong8n0xwaagyl8g" },
{ value: "5", condition: "lessThan", destination: "k3s6gm5ivkc5crpycdbpzkpa" },
],
range: 5,
scale: "smiley",
headline: "How would you rate this weeks newsletter?",
required: true,
subheader: "",
lowerLabel: "Meh",
upperLabel: "Great",
},
{
id: "k3s6gm5ivkc5crpycdbpzkpa",
type: TSurveyQuestionType.OpenText,
logic: [
{ condition: "submitted", destination: "end" },
{ condition: "skipped", destination: "end" },
],
headline: "What would have made this weeks newsletter more helpful?",
required: false,
placeholder: "Type your answer here...",
inputType: "text",
},
{
id: "l2q1chqssong8n0xwaagyl8g",
html: '<p class="fb-editor-paragraph" dir="ltr"><span>Who thinks like you? You\'d do us a huge favor if you\'d share this weeks episode with your brain friend!</span></p>',
type: TSurveyQuestionType.CTA,
headline: "Thanks! ❤️ Spread the love with ONE friend.",
required: false,
buttonUrl: "https://formbricks.com",
buttonLabel: "Happy to help!",
buttonExternal: true,
dismissButtonLabel: "Find your own friends",
},
],
welcomeCard: welcomeCardDefault,
thankYouCard: thankYouCardDefault,
hiddenFields: {
enabled: false,
},
},
},
];
export const findTemplateByName = (name: string): TTemplate | undefined => {

View File

@@ -5,6 +5,8 @@ import CrowdLogoLight from "@/images/clients/crowd-logo-light.svg";
import FlixbusLogo from "@/images/clients/flixbus-white.svg";
import NILogoDark from "@/images/clients/niLogoDark.svg";
import NILogoLight from "@/images/clients/niLogoWhite.svg";
import OptimoleLogo from "@/images/clients/optimole-logo.svg";
import ThemeisleLogo from "@/images/clients/themeisle-logo.webp";
import AnimationFallback from "@/public/animations/opensource-xm-platform-formbricks-fallback.png";
import { ShieldCheckIcon, StarIcon } from "@heroicons/react/24/outline";
import { usePlausible } from "next-plausible";
@@ -45,48 +47,42 @@ export const Hero: React.FC = ({}) => {
</span>
</p>
<div className="mx-auto mt-5 max-w-2xl items-center px-4 sm:flex sm:justify-center md:mt-6 md:space-x-8 md:px-0">
<div className="grid grid-cols-4 items-center gap-6 pt-2 md:gap-8">
<div className="mx-auto mt-5 max-w-3xl items-center px-4 sm:flex sm:justify-center md:mt-6 md:space-x-8 md:px-0">
<div className="grid grid-cols-6 items-center gap-6 pt-2 md:gap-8">
<Image
src={FlixbusLogo}
alt="Flixbus Flix Flixtrain Logo"
className="rounded-lg pb-1 hover:opacity-100 md:opacity-50"
className="rounded-lg pb-1 "
width={200}
/>
<Image
src={CalLogoLight}
alt="Cal Logo"
className="block rounded-lg hover:opacity-100 md:opacity-50 dark:hidden"
width={170}
/>
<Image
src={CalLogoDark}
alt="Cal Logo"
className="hidden rounded-lg hover:opacity-100 md:opacity-50 dark:block"
width={170}
/>
<Image src={CalLogoLight} alt="Cal Logo" className="block rounded-lg dark:hidden" width={170} />
<Image src={CalLogoDark} alt="Cal Logo" className="hidden rounded-lg dark:block" width={170} />
<Image src={ThemeisleLogo} alt="Neverinstall Logo" className="pb-1" width={200} />
<Image
src={CrowdLogoLight}
alt="Crowd.dev Logo"
className="block rounded-lg pb-1 hover:opacity-100 md:opacity-50 dark:hidden"
className="block rounded-lg pb-1 dark:hidden"
width={200}
/>
<Image
src={CrowdLogoDark}
alt="Crowd.dev Logo"
className="hidden rounded-lg pb-1 hover:opacity-100 md:opacity-50 dark:block"
className="hidden rounded-lg pb-1 dark:block"
width={200}
/>
<Image src={OptimoleLogo} alt="Neverinstall Logo" className="pb-1" width={200} />
<Image src={NILogoDark} alt="Neverinstall Logo" className="block pb-1 dark:hidden" width={200} />
<Image
src={NILogoDark}
src={NILogoLight}
alt="Neverinstall Logo"
className="block pb-1 hover:opacity-100 md:opacity-50 dark:hidden"
className="hidden pb-1 dark:block"
width={200}
/>
<Image
src={NILogoLight}
alt="Neverinstall Logo"
className="hidden pb-1 hover:opacity-100 md:opacity-50 dark:block"
className="hidden pb-1 dark:block"
width={200}
/>
</div>

View File

@@ -47,12 +47,7 @@ export const Steps: React.FC = () => {
<div className="grid md:grid-cols-2 md:items-center md:gap-16">
<div className="order-last w-full rounded-lg bg-slate-100 p-4 sm:py-8 md:order-first dark:bg-slate-800">
<div className="flex h-40 items-center justify-center">
<Button
variant="primary"
className=""
onClick={() => {
setAddEventModalOpen(true);
}}>
<Button variant="primary">
<CursorArrowRaysIcon className="mr-2 h-5 w-5 text-white" />
Add Action
</Button>

View File

@@ -1,5 +1,6 @@
import AuthorJohannes from "@/images/blog/johannes-co-founder-formbricks-small.jpg";
import AuthorOla from "@/images/blog/ola-content-writer.jpg";
import AuthorShubham from "@/images/blog/shubham-engineer.png";
import Image from "next/image";
interface AuthorBoxProps {
@@ -10,12 +11,18 @@ interface AuthorBoxProps {
author: string;
}
const authorImages = {
Johannes: AuthorJohannes,
Ola: AuthorOla,
Shubham: AuthorShubham,
};
export default function AuthorBox({ name, title, date, duration, author }: AuthorBoxProps) {
return (
<div className="mb-8 flex items-center space-x-4 rounded-lg border border-slate-200 bg-slate-100 px-6 py-3 dark:border-slate-700 dark:bg-slate-800">
<Image
className="m-0 rounded-full"
src={author === "Johannes" ? AuthorJohannes : AuthorOla}
src={authorImages[author]}
alt={name}
width={45}
height={45}

View File

@@ -79,6 +79,15 @@ export default function BestPracticeNavigation() {
description: "Give users the chance to share feedback in a single click.",
category: "Boost Retention",
},
{
name: "Improve Newsletter Content",
href: "/improve-newsletter-content",
status: true,
icon: FeedbackIcon,
description: "Improve your newsletter content by showing this survey to your readers.",
category: "Boost Retention",
},
];
return (

View File

@@ -13,7 +13,7 @@ const styles: Record<string, CSSProperties> = {
marginTop: "1rem",
borderRadius: "0.375rem",
fontSize: "0.875rem",
fontWeight: "lighter",
fontWeight: "normal",
color: "#e5e7eb",
},
pre: {
@@ -21,7 +21,7 @@ const styles: Record<string, CSSProperties> = {
},
code: {
textShadow: "none",
color: "#fbbf24",
color: "#333333",
},
};

View File

@@ -60,7 +60,7 @@ export default function LayoutMdx({ meta, children }: Props) {
)}
</header>
)}
<Prose className="prose-h2:text-2xl prose-li:text-base prose-h2:mt-4 prose-p:text-base prose-p:mb-4 prose-h3:text-xl prose-a:text-slate-900 prose-a:hover:text-slate-900 prose-a:text-decoration-brand prose-a:not-italic prose-ul:pl-12">
<Prose className="prose-h2:text-2xl prose-li:text-base prose-h2:mt-6 prose-p:text-base prose-p:mb-4 prose-h3:text-xl prose-a:text-slate-900 prose-a:hover:text-slate-900 prose-a:text-decoration-brand prose-a:not-italic prose-ul:pl-12">
{children}
</Prose>
</article>

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -1,97 +0,0 @@
/*!
* Sanitize an HTML string
* (c) 2021 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {String} str The HTML string to sanitize
* @return {String} The sanitized string
*/
export function cleanHtml(str: string): string {
/**
* Convert the string to an HTML document
* @return {Node} An HTML document
*/
function stringToHTML() {
let parser = new DOMParser();
let doc = parser.parseFromString(str, "text/html");
return doc.body || document.createElement("body");
}
/**
* Remove <script> elements
* @param {Node} html The HTML
*/
function removeScripts(html: Element) {
let scripts = html.querySelectorAll("script");
scripts.forEach((script) => {
script.remove();
});
}
/**
* Check if the attribute is potentially dangerous
* @param {String} name The attribute name
* @param {String} value The attribute value
* @return {Boolean} If true, the attribute is potentially dangerous
*/
/**
* Check if the attribute is potentially dangerous
*/
function isPossiblyDangerous(name: string, value: string): boolean {
let val = value.replace(/\s+/g, "").toLowerCase();
if (
["src", "href", "xlink:href", "srcdoc"].includes(name) &&
(val.includes("javascript:") || val.includes("data:") || val.includes("<script>"))
) {
return true;
}
if (name.startsWith("on")) {
return true;
}
return false;
}
/**
* Remove potentially dangerous attributes from an element
* @param {Node} elem The element
*/
function removeAttributes(elem: Element) {
// Loop through each attribute
// If it's dangerous, remove it
let atts = elem.attributes;
for (let i = atts.length - 1; i >= 0; i--) {
let { name, value } = atts[i];
if (isPossiblyDangerous(name, value)) {
elem.removeAttribute(name);
} else if (name === "srcdoc") {
// Recursively sanitize srcdoc content
elem.setAttribute(name, cleanHtml(value));
}
}
}
/**
* Remove dangerous stuff from the HTML document's nodes
* @param {Node} html The HTML document
*/
/**
* Clean the HTML nodes recursively
* @param {Element} html The HTML element
*/
function clean(html: Element) {
let nodes = Array.from(html.children);
for (let node of nodes) {
removeAttributes(node);
clean(node);
}
}
// Convert the string to HTML
let html = stringToHTML();
// Sanitize it
removeScripts(html);
clean(html);
// If the user wants HTML nodes back, return them
// Otherwise, pass a sanitized string back
return html.innerHTML;
}

View File

@@ -1,19 +1,18 @@
export const handleFeedbackSubmit = async (YesNo: string, pageUrl: string | null) => {
const response_data = {
data: {
isHelpful: YesNo,
pageUrl: pageUrl,
},
isHelpful: YesNo,
pageUrl: pageUrl,
};
const payload = {
response: response_data,
surveyId: process.env.NEXT_PUBLIC_FORMBRICKS_COM_DOCS_FEEDBACK_SURVEY_ID,
finished: true,
data: response_data,
};
try {
const res = await fetch(
`${process.env.NEXT_PUBLIC_FORMBRICKS_COM_API_HOST}/api/v1/client/environments/${process.env.NEXT_PUBLIC_FORMBRICKS_COM_ENVIRONMENT_ID}/responses`,
`${process.env.NEXT_PUBLIC_FORMBRICKS_COM_API_HOST}/api/v1/client/${process.env.NEXT_PUBLIC_FORMBRICKS_COM_ENVIRONMENT_ID}/responses`,
{
method: "POST",
headers: {

View File

@@ -1,6 +1,6 @@
import nextMDX from "@next/mdx";
import { withPlausibleProxy } from "next-plausible";
import { recmaPlugins } from "./mdx/recma.mjs";
import { rehypePlugins } from "./mdx/rehype.mjs";
import { remarkPlugins } from "./mdx/remark.mjs";
@@ -155,11 +155,6 @@ const nextConfig = {
destination: "/docs/self-hosting/migration-guide",
permanent: true,
},
{
source: "/cla",
destination: "https://formbricks.com/clmyhzfrymr4ko00hycsg1tvx",
permanent: true,
},
{
source: "/docs/contributing/gitpod",
destination: "/docs/contributing/setup#gitpod",
@@ -170,6 +165,46 @@ const nextConfig = {
destination: "/community",
permanent: true,
},
{
source: "/docs/actions/why",
destination: "/docs/in-app-surveys/actions",
permanent: true,
},
{
source: "/docs/actions/no-code",
destination: "/docs/in-app-surveys/actions#no-code-actions",
permanent: true,
},
{
source: "/docs/actions/code",
destination: "/docs/in-app-surveys/actions#code-actions",
permanent: true,
},
{
source: "/docs/attributes/why",
destination: "/docs/in-app-surveys/attributes",
permanent: true,
},
{
source: "/docs/attributes/custom-attributes",
destination: "/docs/in-app-surveys/attributes#setting-custom-user-attributes",
permanent: true,
},
{
source: "/docs/attributes/identify-users",
destination: "/docs/in-app-surveys/attributes#identifying-users",
permanent: true,
},
{
source: "/signup",
destination: "https://app.formbricks.com/auth/signup",
permanent: true,
},
{
source: "/blog/preseed-announcement",
destination: "/blog",
permanent: true,
},
];
},
async rewrites() {

View File

@@ -12,7 +12,7 @@
},
"browserslist": "defaults, not ie <= 11",
"dependencies": {
"@algolia/autocomplete-core": "^1.11.0",
"@algolia/autocomplete-core": "^1.13.0",
"@calcom/embed-react": "^1.3.0",
"@docsearch/react": "^3.5.2",
"@formbricks/lib": "workspace:*",
@@ -20,50 +20,51 @@
"@formbricks/ui": "workspace:*",
"@headlessui/react": "^1.7.17",
"@headlessui/tailwindcss": "^0.2.0",
"@heroicons/react": "^2.0.18",
"@mapbox/rehype-prism": "^0.8.0",
"@mdx-js/loader": "^2.3.0",
"@mdx-js/react": "^2.3.0",
"@next/mdx": "13.4.19",
"@heroicons/react": "^2.1.1",
"@mapbox/rehype-prism": "^0.9.0",
"@mdx-js/loader": "^3.0.0",
"@mdx-js/react": "^3.0.0",
"@next/mdx": "14.0.4",
"@paralleldrive/cuid2": "^2.2.2",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-tooltip": "^1.0.6",
"@sindresorhus/slugify": "^2.2.1",
"@tailwindcss/typography": "^0.5.10",
"@types/dompurify": "^3.0.5",
"@types/react-highlight-words": "^0.16.5",
"acorn": "^8.10.0",
"autoprefixer": "^10.4.15",
"clsx": "^2.0.0",
"fast-glob": "^3.3.1",
"flexsearch": "^0.7.31",
"framer-motion": "10.16.4",
"framer-motion": "10.17.8",
"lottie-web": "^5.12.2",
"mdast-util-to-string": "^4.0.0",
"mdx-annotations": "^0.1.3",
"mdx-annotations": "^0.1.4",
"next": "13.4.19",
"next-plausible": "^3.11.1",
"next-seo": "^6.1.0",
"next-plausible": "^3.12.0",
"next-seo": "^6.4.0",
"next-sitemap": "^4.2.3",
"next-themes": "^0.2.1",
"node-fetch": "^3.3.2",
"prism-react-renderer": "^2.0.6",
"prism-react-renderer": "^2.3.1",
"prismjs": "^1.29.0",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-tooltip": "^1.0.6",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-highlight-words": "^0.20.0",
"react-icons": "^4.11.0",
"react-markdown": "^8.0.7",
"react-icons": "^4.12.0",
"react-markdown": "^9.0.1",
"react-responsive-embed": "^2.1.0",
"remark": "^14.0.3",
"remark-gfm": "^3.0.1",
"remark-mdx": "^2.3.0",
"sharp": "^0.32.5",
"shiki": "^0.14.4",
"remark": "^15.0.1",
"remark-gfm": "^4.0.0",
"remark-mdx": "^3.0.0",
"sharp": "^0.33.1",
"shiki": "^0.14.7",
"simple-functional-loader": "^1.2.1",
"tailwindcss": "^3.3.3",
"tailwindcss": "^3.4.0",
"unist-util-filter": "^5.0.1",
"unist-util-visit": "^5.0.0",
"zustand": "^4.4.1"
"zustand": "^4.4.7"
},
"devDependencies": {
"@formbricks/tsconfig": "workspace:*",

View File

@@ -1,41 +1,7 @@
import { Head, Html, Main, NextScript } from "next/document";
const themeScript = `
let isDarkMode = window.matchMedia('(prefers-color-scheme: dark)')
function updateTheme(theme) {
theme = theme ?? window.localStorage.theme ?? 'system'
if (theme === 'dark' || (theme === 'system' && isDarkMode.matches)) {
document.documentElement.classList.add('dark')
} else if (theme === 'light' || (theme === 'system' && !isDarkMode.matches)) {
document.documentElement.classList.remove('dark')
}
return theme
}
function updateThemeWithoutTransitions(theme) {
updateTheme(theme)
document.documentElement.classList.add('[&_*]:!transition-none')
window.setTimeout(() => {
document.documentElement.classList.remove('[&_*]:!transition-none')
}, 0)
}
document.documentElement.setAttribute('data-theme', updateTheme())
new MutationObserver(([{ oldValue }]) => {
let newValue = document.documentElement.getAttribute('data-theme')
if (newValue !== oldValue) {
try {
window.localStorage.setItem('theme', newValue)
} catch {}
updateThemeWithoutTransitions(newValue)
}
}).observe(document.documentElement, { attributeFilter: ['data-theme'], attributeOldValue: true })
isDarkMode.addEventListener('change', () => updateThemeWithoutTransitions())
document.documentElement.classList.remove('dark');
`;
export default function Document() {

View File

@@ -10,6 +10,12 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
description: "Build build custom software on top of your data.",
href: "https://www.appsmith.com",
},
{
name: "Aptabase",
description:
"Analytics for Apps, open source, simple and privacy-friendly. SDKs for Swift, React Native, Electron, Flutter and many others.",
href: "https://aptabase.com",
},
{
name: "Argos",
description: "Argos provides the developer tools to debug tests and detect visual regressions..",
@@ -27,6 +33,12 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
"Cal.com is a scheduling tool that helps you schedule meetings without the back-and-forth emails.",
href: "https://cal.com",
},
{
name: "ClassroomIO.com",
description:
"ClassroomIO is a no-code tool that allows you build and scale your own teaching platform with ease.",
href: "https://www.classroomio.com",
},
{
name: "Crowd.dev",
description:
@@ -116,8 +128,7 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
},
{
name: "Lost Pixel",
description:
"Open source visual regression testing alternative to Percy & Chromatic",
description: "Open source visual regression testing alternative to Percy & Chromatic",
href: "https://lost-pixel.com",
},
{
@@ -148,6 +159,12 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
"Open-Source Docsend Alternative to securely share documents with real-time analytics.",
href: "https://www.papermark.io/",
},
{
name: "Prisma",
description:
"Simplify working with databases. Build, optimize, and grow your app easily with an intuitive data model, type-safety, automated migrations, connection pooling, caching, and real-time db subscriptions.",
href: "https://www.prisma.io",
},
{
name: "Requestly",
description:
@@ -182,6 +199,12 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
"The .NET Web Framework for Makers. Build production ready, full-stack web applications fast without sweating the small stuff.",
href: "https://spark-framework.net",
},
{
name: "Tiledesk",
description:
"The innovative open-source framework for developing LLM-enabled chatbots, Tiledesk empowers developers to create advanced, conversational AI agents.",
href: "https://tiledesk.com",
},
{
name: "Tolgee",
description: "Software localization from A to Z made really easy.",
@@ -205,6 +228,12 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
"A modern CRM offering the flexibility of open-source, advanced features and sleek design.",
href: "https://twenty.com",
},
{
name: "UnInbox",
description:
"Modern email for teams and professionals. Bringing the best of email and messaging into a single, modern, and secure platform.",
href: "https://uninbox.com",
},
{
name: "Unkey",
description:

View File

@@ -1,17 +1,16 @@
import Image from "next/image";
import LayoutMdx from "@/components/shared/LayoutMdx";
import AuthorBox from "@/components/shared/AuthorBox";
import Formbricks from "./open-source-survey-software-free-2023-formbricks-typeform-alternative.png";
import Typebot from "./typebot-open-source-free-conversational-form-builder-survey-software-opensource.jpg";
import LimeSurvey from "./free-survey-tool-limesurvey-open-source-software-opensource.png";
import OpnForm from "./opnform-free-open-source-form-survey-tools-builder-2023-self-hostign.jpg";
import LayoutMdx from "@/components/shared/LayoutMdx";
import Image from "next/image";
import HeaderImage from "./2023-title-best-open-source-survey-software-tools-and-alternatives.png";
import LimeSurvey from "./free-survey-tool-limesurvey-open-source-software-opensource.png";
import Formbricks from "./open-source-survey-software-free-2023-formbricks-typeform-alternative.png";
import OpnForm from "./opnform-free-open-source-form-survey-tools-builder-2023-self-hostign.jpg";
import SurveyJS from "./surveyjs-free-opensource-form-survey-tool-software-to-make-surveys-2023.png";
import Typebot from "./typebot-open-source-free-conversational-form-builder-survey-software-opensource.jpg";
export const meta = {
title: "5 Open Source Survey and Form Tools maintained in 2023",
title: "5 Open Source Survey and Form Tools maintained in 2024",
description:
"Most open source projects get abandoned after a while. But these 5 open source survey tools are still alive and kicking in 2023.",
"Most open source projects get abandoned after a while. But these 5 open source survey tools are still alive and kicking in 2024.",
date: "2023-04-12",
publishedTime: "2023-04-12T12:00:00",
authors: ["Johannes"],
@@ -21,17 +20,17 @@ export const meta = {
<AuthorBox name="Johannes" title="Co-Founder" date="April 7th, 2023" duration="4" author={"Johannes"} />
_Most open source projects get abandoned after a while. But these 5 open source survey tools are still alive and kicking in 2023._
_Most open source projects get abandoned after a while. But these 5 open source survey tools are still alive and kicking in 2024._
<Image
src={HeaderImage}
alt="Open source survey tool self-hostable: Find the 5 best (and maintained) open source survey tool 2023."
alt="Open source survey tool self-hostable: Find the 5 best (and maintained) open source survey tool 2024."
className="rounded-lg w-full"
/>
Looking for the perfect open source survey tool to help you gather valuable insights and improve your business? Look no further!
We've compiled a list of the top 5 open source form and survey tools that are still maintained in 2023. In app surveys, conversational bots, AI-generated surveys: These open source tools offer various features that cater to different needs.
We've compiled a list of the top 5 open source form and survey tools that are still maintained in 2024. In app surveys, conversational bots, AI-generated surveys: These open source tools offer various features that cater to different needs.
## 1. Formbricks - In app micro surveys
@@ -124,7 +123,7 @@ LimeSurvey has been around for at least a decade. It's a powerful survey tool ma
## Summary ☟
In this article, we've rounded up the top 5 open source form and survey tools that are still rocking it in 2023. Perfect for devs who are always on the lookout for the latest and greatest!
In this article, we've rounded up the top 5 open source form and survey tools that are still rocking it in 2024. Perfect for devs who are always on the lookout for the latest and greatest!
1. Formbricks: A game-changer for in app micro surveys, letting you target specific customer segments at any point in their journey. It's still early days, but this bad boy is worth keeping an eye on.

View File

@@ -0,0 +1,309 @@
import AuthorBox from "@/components/shared/AuthorBox";
import LayoutMdx from "@/components/shared/LayoutMdx";
import Image from "next/image";
import CrazyEgg from './crazy-egg-website-optimization-heatmaps-recordings-surveys.png'
import CoverImage from './cover-best-feedbackt-tools-2024-open-source-website-surveys-targeted.webp'
import Formbricks from './formbricks-privacy-first-experience-management.png'
import Hotjar from './hotjar-website-heatmaps-behavior-analytics-tools.png'
import IdeaScale from './idea-and-innovation-management-software-ideaScale.png'
import Mopinion from './mopinion-feedback-for-websites-apps-and-email.png'
import Sprinklr from './sprinklr-unified-customer-experience-management-platform-sprinklr.png'
import SurveyMonkey from './surveyMonkey-the-world-most-popular-free-online-survey-tool.png'
import Qualaroo from './user-research-customer-feedback-software-qualaroo.png'
import UserReport from './userReport-simple-user-engagement-tools-that-help-you-improve.png'
import UserSnap from './usersnap-your-number-one-user-feedback-platform.png'
export const meta = {
title: "Best Website Feedback Tools in 2024",
description:
"The best website feedback tools play a crucial role in both enhancing the user experience and optimizing conversion rates. In this article, we cover 10 of the recommended ones.",
date: "2024-01-16",
publishedTime: "2024-01-16T12:00:00",
authors: ["Olasunkanmi Balogun"],
section: "Website Feedback Tools",
tags: ["Feedback Tools", "Formbricks", "SurveyMonkey", "Mopinion", "Qualaroo", "IdeaScale", "UserReport", "Sprinklr", "Hotjar", "UserSnap", "CrazyEgg"],
};
<Image src={CoverImage} alt="Best Open Source Website Feedback Tools 2024" className="w-full rounded-lg" />
<AuthorBox
name="Olasunkanmi Balogun"
title="Content Writer"
date="January 16th, 2024"
duration="10"
author={"Ola"}
/>
As users navigate your website, their feedback serves as a compass, guiding you toward improvements that resonate with them. Feedback from users provides valuable insights into areas where they might be facing challenges or experiencing dissatisfaction. This information is instrumental in identifying and rectifying pain points within your website's design, navigation, or functionality.
But how do you get this feedback?
Thats where **website feedback tools** come into play. The best website feedback tools play a crucial role in both enhancing the user experience and optimizing conversion rates. These tools are usually equipped with features like:
- Targeted surveys and
- Visual feedback options like screen recordings and
However, choosing the right tool is where the problem may lie. Among the myriad of website feedback tools, this article will uncover 10 of the top recommended tools, each distinguished by a unique feature that sets it apart from the rest.
The water's fine; let's dive in headfirst. 🤸
## The 10 Best Website Feedback Tools 2024
Well categorize the website tools highlighted in this section into three categories.
1. Website Voice Of The Customer (VoC) Feedback Tools
2. Community Feedback Tools
3. Behavioral Analysis Tools
Website VoC Feedback Tools focus on understanding and enhancing user experiences; Community Feedback Tools emphasize collaboration and innovation; and Behavioral Analysis Tools provide deep insights for informed decision-making. These tools ensure businesses not only meet user expectations but also stay agile and competitive in the evolving online environment.
As we explore each tool within these categories, we'll explore their vital roles in the digital landscape, their unique approach to how they offer their services and their shortcomings.
## Website voice of the customer (VoC) feedback tools
These tools, as well see, are tools that help you collect and analyze the opinions and experiences of your website visitors. They gather user data through surveys, providing valuable insights into how users interact with your website and what they think about it. The surveys may take various forms, including CSAT, CES, and NPS, as well as polls and quizzes.
### Formbricks
<Image
src={Formbricks}
alt="Formbricks is a free and open source survey software for in app micro surveys. Ask any user segment at any point in the user journey."
className="rounded-lg w-full"
/>
Formbricks is a unique open-source experience management platform designed to facilitate the collection of qualitative user feedback through highly customizable surveys at various touchpoints in your users' journey. It allows you to create multiple survey types, including CSAT, NPS, and CES, to gather insights effectively.
These surveys can be seamlessly embedded into your design, ensuring feedback is collected at key moments without disrupting the user flow. Alternatively, you can share survey links to gather feedback from diverse online sources, such as social media or blog posts.
#### Unique Approach
Formbricks stands out in its trigger versatility by offering an array of generic triggers to initiate surveys. These triggers include New Session, Exit Intent, 50% scroll, created new event, updated
accessibility, received booking requests, invited team member, created new workflow, and viewed insights. This flexibility ensures your surveys appear at precise moments of relevance to maximize their impact.
Moreover, Formbricks takes customization a step further by allowing users to create bespoke triggers tailored to specific needs. Whether it's based on the URL, innerText, or CSS selectors, you can set up triggers that align precisely with your unique goals. This allows you to trigger surveys based on the exact content the user sees or even interactions with specific buttons or sections.
Additionally, the platform provides actionable insights through intuitive dashboards, making it easy to derive meaningful conclusions from the collected feedback.
#### Shortcomings
Formbricks is still very young and doesnt integrate with as many
third-party tools, although it integrates with popular third-party tools
like Slack, Make.com, and Notion. However, the Formbricks team and open
source community is working on adding more all the time.
**Overall**, Formbricks is built on the largest open source survey infrastructure on GitHub. This ensures a privacy-first approach to gathering and analyzing user feedback. You can [get started](http://formbricks.com/) with a free plan and experience that modern open source software can be even more user-friendly than proprietary solutions.
### SurveyMonkey
<Image
src={SurveyMonkey}
alt="SurveyMonkey is a widely used survey platform offering a robust suite of survey features to cater to diverse needs and research goals."
className="rounded-lg w-full"
/>
SurveyMonkey is a widely used survey platform offering a robust suite of survey features to cater to diverse needs and research goals.
#### Unique Approach
With SurveyMonkey, you have the flexibility to start building your surveys from scratch or utilize the AI (which is backed by openAI) to build templates for you. All you need to do is write a prompt that
includes your survey goals, and AI will do the rest.
It also enables you to integrate your survey data with over 175 third-party tools in your stack, including CMS and marketing automation tools, among others.
#### Shortcoming
SurveyMonkey has been around for over 20 years and looks and feels like that. While it is a proven solution for enterprise buyers, most smaller companies might find it bulky.
**Overall**, whether you are an individual, a business, or even an educator who needs to design polls and quizzes for classroom engagement and gather student feedback, SurveyMonkey can do it.
### Mopinion
<Image
src={Mopinion}
alt="Mopinion is a user feedback software with features to create online surveys."
className="rounded-lg w-full"
/>
Mopinion is a user feedback software with features to create online surveys. With Mopinion, you dont just get feedback; it also offers in-depth analysis opportunities on the feedback for you through data visualization on a customizable dashboard.
#### Unique Approach
What's special about Mopinion is its user-friendly features, like drag-and-drop when you're building your forms. You can make feedback forms for all your digital channels easily. One unique thing is that it offers a fully native SDK for Android and iOS, meaning you can put it right into your app. And if you're into self-hosting to keep more control over your data, Mopinion lets you create self-hosted surveys too.
#### Shortcoming
While Mopinion offers robust features, businesses may find the learning curve for the advanced functionalities quite steep. Users may need some time to familiarize themselves with the platform's
capabilities, especially when creating customized surveys or integrating with various third-party tools
**Overall**, Mopinion plays well with other tools too. It integrates smoothly with third-party tools such as Slack, Google Analytics, Jira, Hubspot, Salesforce, and many more.
### Qualaroo
<Image
src={Qualaroo}
alt="Qualaroo is a user feedback and survey platform designed to help businesses understand the needs and preferences of their website visitors. Qualaroo is geared towards capturing real-time insights from website users."
className="rounded-lg w-full"
/>
Qualaroo is a user feedback and survey platform designed to help businesses understand the needs and preferences of their website visitors. Qualaroo is geared towards capturing real-time insights from website users to enhance the user experience and inform business decisions.
It does this through something called "Nudges" these are subtle little surveys that pop up at just the right times on your website. They don't interrupt what visitors are doing; instead, they smoothly blend into the user's journey.
With Qualaroo, you have different survey types to choose from, like custom surveys, NPS (Net Promoter Score), PMF (Product-Market Fit), and on-site surveys. Plus, there's a special dashboard just for NPS surveys that lets you keep an eye on scores in real time.
What's cool is that you can customize these surveys to target specific user behaviors. You can ask for feedback based on where users are, who they are, when they visit, and more; it's like tailoring questions to fit the person.
#### Unique Approach
Qualaroo stands out with its innovative approach to gathering user insights. It leverages unobtrusive survey "Nudges" that appear at strategic moments on a website.
#### Shortcoming
There may be a risk of feedback bias since users can choose whether or not to engage with the Nudges.
**Overall**, Qualaroo plays well with other popular tools that businesses use. So, whether you're a small startup or a big corporation, Qualaroo is here to make your website the best it can be.
### 2. Community Feedback Tools
These are platforms designed to facilitate and manage feedback from a community of users or customers of a business. With these tools, you can gather opinions, suggestions, and insights from a group of people who share a common interest or connection, such as users of a particular
product, members of an online community, or participants in a specific project.
### IdeaScale
<Image
src={IdeaScale}
alt="IdeaScale is an innovation management solution that links organizations to people with ideas."
className="rounded-lg w-full"
/>
IdeaScale describes itself as an innovation management solution that links organizations to people with ideas.
### Unique Approach
IdeaScale stands out in its approach to connecting organizations with people who contribute ideas by providing an idea hub for users to submit and discuss ideas openly. Some of its other features on this platform include an idea submission feature, which enables you to easily share an idea and add all the relevant details so that anyone can view, validate, or add to that idea; a similarity search to reduce redundancy by proactively searching for similar ideas; and idea linking and annotations to identify trends and relationships between ideas by linking ideas and showcasing how they build on one another.
### Shortcoming
Nonetheless, while IdeaScale offers valuable features, it presents the challenge of managing large volumes of ideas. As the platform encourages open submission, there might be a need for effective mechanisms to sift through and prioritize ideas, ensuring that valuable contributions receive due attention.
**Overall,** IdeaScale facilitates the collaborative exchange of insights, making it a valuable tool for businesses seeking feedback and innovation from their community.
### UserReport
<Image
src={UserReport}
alt="UserReport helps you resonate with your users."
className="rounded-lg w-full"
/>
UserReport helps you resonate with your users. It tells you who your users are and what they want to achieve. It is based primarily on two features, the survey widget and the feedback widget.
#### Unique Approach
Through its survey widget, the tool gathers essential information about your website visitors. However, it's the feedback widget that transforms UserReport into a dynamic space for community engagement. Here, users actively participate by posting, voting on, and discussing ideas. This active involvement shifts the tool from a passive data collector to a platform where users contribute thoughts and opinions, essentially becoming co-creators in shaping the direction of your
platform.
#### Shortcoming
However, as with any community-driven tool, managing and prioritizing a large volume of user-generated content may pose a challenge. Additionally, the effectiveness of UserReport relies heavily on users actively participating in surveys, providing feedback, and contributing ideas. Hence, if user engagement is low, the platform may not harness its full potential.
**Overall**, with UserReport, you're not just getting data; you're building a bridge to your users' thoughts and creating a vibrant community where everyone's voice matters.
### Sprinklr Social
<Image
src={Sprinklr}
alt="Sprinklr is a platform for unified customer experience management."
className="rounded-lg w-full"
/>
Sprinklr boasts of being the first platform purpose-built for unified customer experience management.
#### Unique Approach
It introduces the concept of social listening through its comprehensive product suite, notably Sprinklr Social, a standout among G2s Top 50 Products for Marketers. Unlike traditional customer experience platforms, Sprinklr Social goes beyond managing online presence; it delves into social listening, actively engaging businesses with their audience.
Sprinklr Social is a comprehensive tool that helps businesses manage their online presence, engage with their audience, and gather valuable insights just from its centralized dashboard.
#### Shortcoming
However, despite Sprinklrs strength, businesses might face a learning curve in fully harnessing the platform's capabilities. The need for training and support to navigate and utilize all aspects efficiently could be a consideration before using this tool.
In essence, Sprinklr serves as a community feedback tool by not only allowing businesses to listen to their audience but also by actively engaging with the community, gathering feedback, and fostering meaningful interactions across various social media platforms.
### 3. Behavioural Analysis Tools
These tools go beyond traditional analytics tools that track page views and clicks. They go deeper into how a user behaves on your website, user motivations, and pain points. A typical behavioral
analysis tool will offer features like session recordings, heatmaps, and funnels.
Lets have a look at three of the recommended ones.
### Hotjar
<Image
src={Hotjar}
alt="Hotjar is a powerful behavioral analysis tool that lets you see, understand, and optimize how people interact with your website."
className="rounded-lg w-full"
/>
Hotjar is a powerful behavioral analysis tool that lets you see, understand, and optimize how people interact with your website.
#### Unique Approach
With Hotjar, when you sign up, you get several behavior analytics tools all at once, all from the same dashboard. These tools, including heatmaps and recordings, help you see whats happening with users on your website.
#### Shortcoming
A potential shortcoming of Hotjar lies in its data sampling approach, particularly in standard plans. Users are limited to reviewing only a fraction of the entire dataset collected daily. For instance, if you have 3000 recordings per month, they are restricted to analyzing just 100 daily sessions. This sampling limitation could pose challenges for businesses aiming to conduct a comprehensive analysis of user interactions, potentially impacting the depth and accuracy of insights derived from the collected data.
**Overall**, Hotjar integrates with a wide range of third-party tools you may already be using. This makes it particularly suitable for you if you are an enterprise with diverse third-party tools in your tech stack, as it complements and enhances your existing analytics ecosystem.
### Usersnap
<Image
src={UserSnap}
alt="Usersnap is a visual feedback and bug-tracking tool that helps you to capture, organize, respond to, and scale user feedback all in one place."
className="rounded-lg w-full"
/>
Usersnap is a visual feedback and bug-tracking tool that helps you to capture, organize, respond to, and scale user feedback all in one place.
#### Unique Approach
At its core, Usersnap revolutionizes user interaction insights by offering a robust platform for capturing screenshots and annotating them. This visual feedback becomes a crucial lens through which development and design teams can analyze how users engage with various elements on a website, gaining qualitative insights into preferences, pain points, and areas of interest.
#### Shortcoming
Some of its users complain of the absence of search functionality or filtering options within the list of submitted feedback. Users navigating through their feedback submissions cannot efficiently search for specific types of feedback or filter submissions based on criteria. This limitation can hinder users' ability to quickly locate and review particular feedback instances or determine whether they have previously submitted similar feedback.
**Overall,** Usersnap integrates with popular collaboration tools such as Jira, Slack, and Trello. This ensures that the behavioral insights gleaned from Usersnap are seamlessly woven into broader project workflows, fostering collaboration and informed decision-making.
### CrazyEgg
<Image
src={CrazyEgg}
alt="CrazyEgg gives you visual insights into how people interact with your website, helping you see patterns, identify pain points, and optimize for success."
className="rounded-lg w-full"
/>
CrazyEgg gives you visual insights into how people interact with your website, helping you see patterns, identify pain points, and optimize for success.
#### Unique Approach
With CrazyEgg session recordings, you can watch your users click, scroll, and navigate through your website just like you are virtually standing right beside them.
On the other hand, CrazyEgg boasts of being the originator of webpage heatmap technology. It takes a snapshot of your web pages and creates heatmaps showing where users focus the most. But that's not all you also get four other reports: the Scrollmap report, Confetti report, Overlay report, and List report. Each report gives you more insights into how users engage with your site. If you're curious about these reports, you can check out their website for detailed information.
#### Shortcoming
A notable challenge reported by users of CrazyEgg is the perceived lack of detailed reporting within the platform. Feedback suggests that the existing reporting features may not provide users with sufficient depth of information, leaving them wanting more comprehensive insights. The perceived limitation in detailed reporting could impact the platform's effectiveness for users who seek in-depth analytics to drive strategic improvements on their websites.
**Overall**, CrazyEgg stands out for its innovative approach to behavioral analysis and its role in enhancing website optimization strategies.
## In Conclusion
Website feedback tools offer businesses many possibilities to make websites better for users and increase how many people take desired actions. One tool, CrazyEgg, gives visual insights and real-time feedback, helping businesses understand how users interact with their websites. It lets you watch users move through the website and see patterns with session recordings and heatmaps.
Each tool, like Formbricks, plays a crucial role in improving digital experiences. Formbricks, especially, is unique as it is built on an open-source platform. It allows businesses to create flexible and customizable surveys for users. Being open source means it encourages collaboration, letting businesses adapt and contribute to its development. This approach emphasizes transparency and community-driven innovation, ensuring a user-friendly digital space.
export default ({ children }) => <LayoutMdx meta={meta}>{children}</LayoutMdx>;

Some files were not shown because too many files have changed in this diff Show More