Compare commits
90 Commits
v3.0.0
...
release-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7012f27391 | ||
|
|
510fe3902e | ||
|
|
2bc23594ad | ||
|
|
06e00f3066 | ||
|
|
9b3d409695 | ||
|
|
f7f5737abf | ||
|
|
458f135ee1 | ||
|
|
8e116bf62d | ||
|
|
f1d697a83f | ||
|
|
69a7a57f41 | ||
|
|
24de1559a5 | ||
|
|
ec29abfcaf | ||
|
|
eac97db665 | ||
|
|
d8386328e7 | ||
|
|
d28f321aa2 | ||
|
|
e691c076a1 | ||
|
|
ad842e0e80 | ||
|
|
dcf4109c5b | ||
|
|
05287c135e | ||
|
|
6ff8ec21cf | ||
|
|
7b6e22aa04 | ||
|
|
ee56914285 | ||
|
|
a2e9cd3c43 | ||
|
|
359f29a264 | ||
|
|
576b15fec0 | ||
|
|
42434290da | ||
|
|
62c6189dfd | ||
|
|
21c9ebbca3 | ||
|
|
658d4687f9 | ||
|
|
3775453db8 | ||
|
|
edcaf8e639 | ||
|
|
3aa658a64e | ||
|
|
58fc66ad1c | ||
|
|
f68f87645f | ||
|
|
25f99da172 | ||
|
|
5da6faa972 | ||
|
|
02b25138ef | ||
|
|
21644f5ad8 | ||
|
|
d3adc1629c | ||
|
|
7c60c57c60 | ||
|
|
7006a790dc | ||
|
|
2575b649a0 | ||
|
|
8399391aaa | ||
|
|
dfbec20016 | ||
|
|
17ac777e9b | ||
|
|
01edc0e6e0 | ||
|
|
d6b58a5e66 | ||
|
|
517ef9515c | ||
|
|
7d94861db9 | ||
|
|
cb1e4fa583 | ||
|
|
dd5fced6c4 | ||
|
|
01a4d91167 | ||
|
|
2e2f0fdbb5 | ||
|
|
3ca1a72c6a | ||
|
|
9905199055 | ||
|
|
5970ff917f | ||
|
|
d197c91995 | ||
|
|
6e1ee6df12 | ||
|
|
b44d6e60bd | ||
|
|
1d0e49d5b6 | ||
|
|
ced7b2aa2c | ||
|
|
6aa473c316 | ||
|
|
aebe36b9e8 | ||
|
|
71c92766d3 | ||
|
|
a3f5f7645a | ||
|
|
7e8514e7be | ||
|
|
7715789d0f | ||
|
|
a93fed448f | ||
|
|
10738a7af0 | ||
|
|
2c00c55e5d | ||
|
|
80ba02851f | ||
|
|
5fd3190a2d | ||
|
|
117ec317de | ||
|
|
f4f2836bdb | ||
|
|
e194a2feb8 | ||
|
|
93e9ec867c | ||
|
|
1fe625a9b4 | ||
|
|
1c1ef56e00 | ||
|
|
838fe16845 | ||
|
|
7f3c45f85a | ||
|
|
9a4f6721e2 | ||
|
|
a4ffc03e55 | ||
|
|
c4c98bda31 | ||
|
|
63aa2fd307 | ||
|
|
99d0b1786d | ||
|
|
843fed5ffd | ||
|
|
9b8112b478 | ||
|
|
2433d40918 | ||
|
|
2c1f473bbe | ||
|
|
7605a4d835 |
14
.env.example
@@ -46,6 +46,9 @@ SMTP_SECURE_ENABLED=0
|
||||
SMTP_USER=smtpUser
|
||||
SMTP_PASSWORD=smtpPassword
|
||||
|
||||
# If set to 0, the server will not require SMTP_USER and SMTP_PASSWORD(default is 1)
|
||||
# SMTP_AUTHENTICATED=
|
||||
|
||||
# If set to 0, the server will accept connections without requiring authorization from the list of supplied CAs (default is 1).
|
||||
# SMTP_REJECT_UNAUTHORIZED_TLS=0
|
||||
|
||||
@@ -101,6 +104,11 @@ PASSWORD_RESET_DISABLED=1
|
||||
PRIVACY_URL=
|
||||
TERMS_URL=
|
||||
IMPRINT_URL=
|
||||
IMPRINT_ADDRESS=
|
||||
|
||||
# Configure Turnstile in signup flow
|
||||
# NEXT_PUBLIC_TURNSTILE_SITE_KEY=
|
||||
# TURNSTILE_SECRET_KEY=
|
||||
|
||||
# Configure Github Login
|
||||
GITHUB_ID=
|
||||
@@ -159,9 +167,9 @@ ENTERPRISE_LICENSE_KEY=
|
||||
# DEFAULT_ORGANIZATION_ID=
|
||||
# DEFAULT_ORGANIZATION_ROLE=owner
|
||||
|
||||
# Send new users to customer.io
|
||||
# CUSTOMER_IO_API_KEY=
|
||||
# CUSTOMER_IO_SITE_ID=
|
||||
# Send new users to Brevo
|
||||
# BREVO_API_KEY=
|
||||
# BREVO_LIST_ID=
|
||||
|
||||
# Ignore Rate Limiting across the Formbricks app
|
||||
# RATE_LIMITING_DISABLED=1
|
||||
|
||||
4
.github/workflows/build-docs.yml
vendored
@@ -1,6 +1,10 @@
|
||||
name: Build Docs
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Docs
|
||||
|
||||
4
.github/workflows/build-web.yml
vendored
@@ -1,6 +1,10 @@
|
||||
name: Build Web
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Formbricks-web
|
||||
|
||||
92
.github/workflows/codeql.yml
vendored
@@ -1,92 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL Advanced"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
schedule:
|
||||
- cron: '17 1 * * 1'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners (GitHub.com only)
|
||||
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
permissions:
|
||||
# required for all workflows
|
||||
security-events: write
|
||||
|
||||
# required to fetch internal or private CodeQL packs
|
||||
packages: read
|
||||
|
||||
# only required for workflows in private repositories
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- language: javascript-typescript
|
||||
build-mode: none
|
||||
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
|
||||
# Use `c-cpp` to analyze code written in C, C++ or both
|
||||
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
|
||||
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
|
||||
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
|
||||
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# If the analyze step fails for one of the languages you are analyzing with
|
||||
# "We were unable to automatically build your code", modify the matrix above
|
||||
# to set the build mode to "manual" for that language. Then modify this step
|
||||
# to build your code.
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
- if: matrix.build-mode == 'manual'
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'If you are using a "manual" build mode for one or more of the' \
|
||||
'languages you are analyzing, replace this with the commands to build' \
|
||||
'your code, for example:'
|
||||
echo ' make bootstrap'
|
||||
echo ' make release'
|
||||
exit 1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
@@ -7,6 +7,10 @@ on:
|
||||
schedule:
|
||||
# Runs "At 00:00." (see https://crontab.guru)
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
cron-weeklySummary:
|
||||
env:
|
||||
|
||||
2
.github/workflows/cron-weeklySummary.yml
vendored
@@ -9,6 +9,8 @@ on:
|
||||
- cron: "0 8 * * 1"
|
||||
jobs:
|
||||
cron-weeklySummary:
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
APP_URL: ${{ secrets.APP_URL }}
|
||||
CRON_SECRET: ${{ secrets.CRON_SECRET }}
|
||||
|
||||
47
.github/workflows/e2e.yml
vendored
@@ -1,9 +1,28 @@
|
||||
name: E2E Tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
secrets:
|
||||
AZURE_CLIENT_ID:
|
||||
required: false
|
||||
AZURE_TENANT_ID:
|
||||
required: false
|
||||
AZURE_SUBSCRIPTION_ID:
|
||||
required: false
|
||||
PLAYWRIGHT_SERVICE_URL:
|
||||
required: false
|
||||
# Add other secrets if necessary
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
TELEMETRY_DISABLED: 1
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
actions: read
|
||||
checks: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Run E2E Tests
|
||||
@@ -83,11 +102,35 @@ jobs:
|
||||
- name: Install Playwright
|
||||
run: pnpm exec playwright install --with-deps
|
||||
|
||||
- name: Run E2E Tests
|
||||
- name: Set Azure Secret Variables
|
||||
run: |
|
||||
if [[ -n "${{ secrets.AZURE_CLIENT_ID }}" && -n "${{ secrets.AZURE_TENANT_ID }}" && -n "${{ secrets.AZURE_SUBSCRIPTION_ID }}" ]]; then
|
||||
echo "AZURE_ENABLED=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "AZURE_ENABLED=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Azure login
|
||||
if: env.AZURE_ENABLED == 'true'
|
||||
uses: azure/login@v2
|
||||
with:
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||
|
||||
- name: Run E2E Tests (Azure)
|
||||
if: env.AZURE_ENABLED == 'true'
|
||||
env:
|
||||
PLAYWRIGHT_SERVICE_URL: ${{ secrets.PLAYWRIGHT_SERVICE_URL }}
|
||||
run: |
|
||||
pnpm test-e2e:azure
|
||||
|
||||
- name: Run E2E Tests (Local)
|
||||
if: env.AZURE_ENABLED == 'false'
|
||||
run: |
|
||||
pnpm test:e2e
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report
|
||||
|
||||
10
.github/workflows/lint.yml
vendored
@@ -1,6 +1,10 @@
|
||||
name: Lint
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Linters
|
||||
@@ -8,16 +12,16 @@ jobs:
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
- uses: ./.github/actions/dangerous-git-checkout
|
||||
|
||||
- name: Setup Node.js 20.x
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --config.platform=linux --config.architecture=x64
|
||||
|
||||
39
.github/workflows/pr.yml
vendored
@@ -1,5 +1,13 @@
|
||||
name: PR Update
|
||||
|
||||
# Update permissions to include all necessary ones
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
actions: read
|
||||
checks: write
|
||||
id-token: write
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
@@ -12,55 +20,28 @@ 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 Unit 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
|
||||
|
||||
docs:
|
||||
name: Build Docs
|
||||
needs: [changes]
|
||||
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
|
||||
uses: ./.github/workflows/build-docs.yml
|
||||
secrets: inherit
|
||||
|
||||
e2e-test:
|
||||
name: Run E2E Tests
|
||||
needs: [changes]
|
||||
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
|
||||
uses: ./.github/workflows/e2e.yml
|
||||
secrets: inherit
|
||||
|
||||
@@ -69,6 +50,10 @@ jobs:
|
||||
needs: [lint, test, build, e2e-test, docs]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
checks: write
|
||||
statuses: write
|
||||
steps:
|
||||
- name: fail if conditional jobs failed
|
||||
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'skipped') || contains(needs.*.result, 'cancelled')
|
||||
|
||||
62
.github/workflows/prepare-release.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Prepare release
|
||||
run-name: Prepare release ${{ inputs.next_version }}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
next_version:
|
||||
required: true
|
||||
type: string
|
||||
description: "Version name"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
prepare_release:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
|
||||
- uses: ./.github/actions/dangerous-git-checkout
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config --local user.email "github-actions@github.com"
|
||||
git config --local user.name "GitHub Actions"
|
||||
|
||||
- name: Setup Node.js 20.x
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --config.platform=linux --config.architecture=x64
|
||||
|
||||
- name: Bump version
|
||||
run: |
|
||||
cd apps/web
|
||||
pnpm version ${{ inputs.next_version }} --no-workspaces-update
|
||||
|
||||
- name: Commit changes and create a branch
|
||||
run: |
|
||||
branch_name="release-v${{ inputs.next_version }}"
|
||||
git checkout -b "$branch_name"
|
||||
git add .
|
||||
git commit -m "chore: release v${{ inputs.next_version }}"
|
||||
git push origin "$branch_name"
|
||||
|
||||
- name: Create pull request
|
||||
run: |
|
||||
gh pr create \
|
||||
--base main \
|
||||
--head "release-v${{ inputs.next_version }}" \
|
||||
--title "chore: bump version to v${{ inputs.next_version }}" \
|
||||
--body "This PR contains the changes for the v${{ inputs.next_version }} release."
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
5
.github/workflows/release-changesets.yml
vendored
@@ -6,6 +6,11 @@ on:
|
||||
# branches:
|
||||
# - main
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
packages: write
|
||||
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
env:
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
name: Docker for Data Migrations
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
env:
|
||||
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
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# https://github.com/docker/setup-qemu-action
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
# https://github.com/docker/setup-buildx-action
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Install cosign
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: sigstore/cosign-installer@v3.5.0
|
||||
|
||||
- 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 }}
|
||||
type=raw,value=latest
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
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 }}
|
||||
cosign sign --yes ghcr.io/${{ env.IMAGE_NAME }}:latest
|
||||
2
.github/workflows/release-docker.yml
vendored
@@ -8,6 +8,8 @@ on:
|
||||
jobs:
|
||||
release-image-on-dockerhub:
|
||||
name: Release on Dockerhub
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
|
||||
23
.github/workflows/sonarqube.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: SonarQube
|
||||
on:
|
||||
workflow_dispatch:
|
||||
# push:
|
||||
# branches:
|
||||
# - main
|
||||
# pull_request:
|
||||
# types: [opened, synchronize, reopened]
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
sonarqube:
|
||||
name: SonarQube
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: SonarQube Scan
|
||||
uses: SonarSource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
2
.github/workflows/test.yml
vendored
@@ -6,6 +6,8 @@ jobs:
|
||||
name: Unit Tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
@@ -3,7 +3,7 @@ name: "Welcome new contributors"
|
||||
on:
|
||||
issues:
|
||||
types: opened
|
||||
pull_request:
|
||||
pull_request_target:
|
||||
types: opened
|
||||
|
||||
permissions:
|
||||
|
||||
3
.gitignore
vendored
@@ -35,9 +35,6 @@ yarn-error.log*
|
||||
!packages/database/.env
|
||||
!apps/web/.env
|
||||
|
||||
# Prisma generated files
|
||||
packages/database/zod
|
||||
|
||||
# turbo
|
||||
.turbo
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { StatusBar } from "expo-status-bar";
|
||||
import type { JSX } from "react";
|
||||
import React, { type JSX } from "react";
|
||||
import { Button, LogBox, StyleSheet, Text, View } from "react-native";
|
||||
import Formbricks, { track } from "@formbricks/react-native";
|
||||
|
||||
@@ -15,8 +15,8 @@ export default function App(): JSX.Element {
|
||||
}
|
||||
|
||||
const config = {
|
||||
environmentId: process.env.EXPO_PUBLIC_FORMBRICKS_ENVIRONMENT_ID,
|
||||
apiHost: process.env.EXPO_PUBLIC_API_HOST,
|
||||
environmentId: process.env.EXPO_PUBLIC_FORMBRICKS_ENVIRONMENT_ID as string,
|
||||
apiHost: process.env.EXPO_PUBLIC_API_HOST as string,
|
||||
userId: "random-user-id",
|
||||
attributes: {
|
||||
language: "en",
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ["@formbricks/eslint-config/legacy-next.js"],
|
||||
extends: ["@formbricks/eslint-config/next.js"],
|
||||
parserOptions: {
|
||||
project: "tsconfig.json",
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Sidebar } from "./Sidebar";
|
||||
import { Sidebar } from "./sidebar";
|
||||
|
||||
export const LayoutApp = ({ children }: { children: React.ReactNode }) => {
|
||||
export function LayoutApp({ children }: { children: React.ReactNode }): React.JSX.Element {
|
||||
return (
|
||||
<div className="min-h-full">
|
||||
{/* Static sidebar for desktop */}
|
||||
@@ -10,4 +10,4 @@ export const LayoutApp = ({ children }: { children: React.ReactNode }) => {
|
||||
<div className="flex flex-1 flex-col lg:pl-64">{children}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -25,7 +25,7 @@ const secondaryNavigation = [
|
||||
{ name: "Privacy", href: "#", icon: ShieldCheckIcon },
|
||||
];
|
||||
|
||||
export const Sidebar = () => {
|
||||
export function Sidebar(): React.JSX.Element {
|
||||
return (
|
||||
<div className="flex flex-grow flex-col overflow-y-auto bg-cyan-700 pb-4 pt-5">
|
||||
<nav
|
||||
@@ -62,4 +62,4 @@ export const Sidebar = () => {
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
export const classNames = (...classes: any) => {
|
||||
export function classNames(...classes: string[]): string {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"dependencies": {
|
||||
"@formbricks/js": "workspace:*",
|
||||
"lucide-react": "0.468.0",
|
||||
"next": "15.1.0",
|
||||
"next": "15.1.2",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
},
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { AppProps } from "next/app";
|
||||
import Head from "next/head";
|
||||
import "../globals.css";
|
||||
|
||||
const App = ({ Component, pageProps }: AppProps) => {
|
||||
export default function App({ Component, pageProps }: AppProps): React.JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@@ -17,6 +17,4 @@ const App = ({ Component, pageProps }: AppProps) => {
|
||||
<Component {...pageProps} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Head, Html, Main, NextScript } from "next/document";
|
||||
|
||||
const Document = () => {
|
||||
export default function Document(): React.JSX.Element {
|
||||
return (
|
||||
<Html lang="en" className="h-full bg-slate-50">
|
||||
<Head />
|
||||
@@ -10,6 +10,4 @@ const Document = () => {
|
||||
</body>
|
||||
</Html>
|
||||
);
|
||||
};
|
||||
|
||||
export default Document;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ import { useEffect, useState } from "react";
|
||||
import formbricks from "@formbricks/js";
|
||||
import fbsetup from "../public/fb-setup.png";
|
||||
|
||||
declare const window: any;
|
||||
declare const window: Window;
|
||||
|
||||
const AppPage = ({}) => {
|
||||
export default function AppPage(): React.JSX.Element {
|
||||
const [darkMode, setDarkMode] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
@@ -19,43 +19,52 @@ const AppPage = ({}) => {
|
||||
}, [darkMode]);
|
||||
|
||||
useEffect(() => {
|
||||
// enable Formbricks debug mode by adding formbricksDebug=true GET parameter
|
||||
const addFormbricksDebugParam = () => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (!urlParams.has("formbricksDebug")) {
|
||||
urlParams.set("formbricksDebug", "true");
|
||||
const newUrl = `${window.location.pathname}?${urlParams.toString()}`;
|
||||
window.history.replaceState({}, "", newUrl);
|
||||
const initFormbricks = () => {
|
||||
// enable Formbricks debug mode by adding formbricksDebug=true GET parameter
|
||||
const addFormbricksDebugParam = (): void => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (!urlParams.has("formbricksDebug")) {
|
||||
urlParams.set("formbricksDebug", "true");
|
||||
const newUrl = `${window.location.pathname}?${urlParams.toString()}`;
|
||||
window.history.replaceState({}, "", newUrl);
|
||||
}
|
||||
};
|
||||
|
||||
addFormbricksDebugParam();
|
||||
|
||||
if (process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID && process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST) {
|
||||
const userId = "THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING";
|
||||
const userInitAttributes = {
|
||||
language: "de",
|
||||
"Init Attribute 1": "eight",
|
||||
"Init Attribute 2": "two",
|
||||
};
|
||||
|
||||
void formbricks.init({
|
||||
environmentId: process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID,
|
||||
apiHost: process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST,
|
||||
userId,
|
||||
attributes: userInitAttributes,
|
||||
});
|
||||
}
|
||||
|
||||
// Connect next.js router to Formbricks
|
||||
if (process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID && process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST) {
|
||||
const handleRouteChange = formbricks.registerRouteChange;
|
||||
|
||||
router.events.on("routeChangeComplete", () => {
|
||||
void handleRouteChange();
|
||||
});
|
||||
|
||||
return () => {
|
||||
router.events.off("routeChangeComplete", () => {
|
||||
void handleRouteChange();
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
addFormbricksDebugParam();
|
||||
|
||||
if (process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID && process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST) {
|
||||
const userId = "THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING";
|
||||
const userInitAttributes = {
|
||||
language: "de",
|
||||
"Init Attribute 1": "eight",
|
||||
"Init Attribute 2": "two",
|
||||
};
|
||||
|
||||
formbricks.init({
|
||||
environmentId: process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID,
|
||||
apiHost: process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST,
|
||||
userId,
|
||||
attributes: userInitAttributes,
|
||||
});
|
||||
}
|
||||
|
||||
// Connect next.js router to Formbricks
|
||||
if (process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID && process.env.NEXT_PUBLIC_FORMBRICKS_API_HOST) {
|
||||
const handleRouteChange = formbricks?.registerRouteChange;
|
||||
router.events.on("routeChangeComplete", handleRouteChange);
|
||||
|
||||
return () => {
|
||||
router.events.off("routeChangeComplete", handleRouteChange);
|
||||
};
|
||||
}
|
||||
initFormbricks();
|
||||
}, [router.events]);
|
||||
|
||||
return (
|
||||
@@ -74,8 +83,11 @@ const AppPage = ({}) => {
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="mt-2 rounded-lg bg-slate-200 px-6 py-1 dark:bg-slate-700 dark:text-slate-100"
|
||||
onClick={() => setDarkMode(!darkMode)}>
|
||||
onClick={() => {
|
||||
setDarkMode(!darkMode);
|
||||
}}>
|
||||
{darkMode ? "Toggle Light Mode" : "Toggle Dark Mode"}
|
||||
</button>
|
||||
</div>
|
||||
@@ -96,8 +108,8 @@ const AppPage = ({}) => {
|
||||
{process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID}
|
||||
</strong>
|
||||
<span className="relative ml-2 flex h-3 w-3">
|
||||
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-green-500 opacity-75"></span>
|
||||
<span className="relative inline-flex h-3 w-3 rounded-full bg-green-500"></span>
|
||||
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-green-500 opacity-75" />
|
||||
<span className="relative inline-flex h-3 w-3 rounded-full bg-green-500" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,9 +120,6 @@ const AppPage = ({}) => {
|
||||
Look at the logs to understand how the widget works.{" "}
|
||||
<strong className="dark:text-white">Open your browser console</strong> to see the logs.
|
||||
</p>
|
||||
{/* <div className="max-h-[40vh] overflow-y-auto py-4">
|
||||
<LogsContainer />
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -125,8 +134,9 @@ const AppPage = ({}) => {
|
||||
</p>
|
||||
<button
|
||||
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"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
formbricks.reset();
|
||||
void formbricks.reset();
|
||||
}}>
|
||||
Reset
|
||||
</button>
|
||||
@@ -138,7 +148,9 @@ const 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-slate-700 dark:hover:bg-slate-600">
|
||||
<button
|
||||
type="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>
|
||||
@@ -147,6 +159,7 @@ const AppPage = ({}) => {
|
||||
This button sends a{" "}
|
||||
<a
|
||||
href="https://formbricks.com/docs/actions/no-code"
|
||||
rel="noopener noreferrer"
|
||||
className="underline dark:text-blue-500"
|
||||
target="_blank">
|
||||
No Code Action
|
||||
@@ -154,6 +167,7 @@ const AppPage = ({}) => {
|
||||
as long as you created it beforehand in the Formbricks App.{" "}
|
||||
<a
|
||||
href="https://formbricks.com/docs/actions/no-code"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
className="underline dark:text-blue-500">
|
||||
Here are instructions on how to do it.
|
||||
@@ -164,8 +178,9 @@ const AppPage = ({}) => {
|
||||
<div className="p-6">
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
formbricks.setAttribute("Plan", "Free");
|
||||
void formbricks.setAttribute("Plan", "Free");
|
||||
}}
|
||||
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 'Free'
|
||||
@@ -177,6 +192,7 @@ const AppPage = ({}) => {
|
||||
<a
|
||||
href="https://formbricks.com/docs/attributes/custom-attributes"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="underline dark:text-blue-500">
|
||||
attribute
|
||||
</a>{" "}
|
||||
@@ -187,8 +203,9 @@ const AppPage = ({}) => {
|
||||
<div className="p-6">
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
formbricks.setAttribute("Plan", "Paid");
|
||||
void formbricks.setAttribute("Plan", "Paid");
|
||||
}}
|
||||
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 'Paid'
|
||||
@@ -200,6 +217,7 @@ const AppPage = ({}) => {
|
||||
<a
|
||||
href="https://formbricks.com/docs/attributes/custom-attributes"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="underline dark:text-blue-500">
|
||||
attribute
|
||||
</a>{" "}
|
||||
@@ -210,8 +228,9 @@ const AppPage = ({}) => {
|
||||
<div className="p-6">
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
formbricks.setEmail("test@web.com");
|
||||
void 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-slate-700 dark:hover:bg-slate-600">
|
||||
Set Email
|
||||
@@ -223,6 +242,7 @@ const AppPage = ({}) => {
|
||||
<a
|
||||
href="https://formbricks.com/docs/attributes/identify-users"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="underline dark:text-blue-500">
|
||||
user email
|
||||
</a>{" "}
|
||||
@@ -234,6 +254,4 @@ const AppPage = ({}) => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppPage;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
module.exports = {
|
||||
extends: ["@formbricks/eslint-config/legacy-next.js"],
|
||||
root: true,
|
||||
extends: ["@formbricks/eslint-config/next.js"],
|
||||
parserOptions: {
|
||||
project: "tsconfig.json",
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
rules: {
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"import/no-cycle": "off",
|
||||
},
|
||||
settings: {
|
||||
"import/resolver": {
|
||||
typescript: {
|
||||
project: "tsconfig.json",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
|
||||
import AddMember from "./images/add-member.webp";
|
||||
import BulkInvite from "./images/bulk-invite.webp";
|
||||
@@ -20,8 +20,7 @@ Learn about the different organization-level and team-level roles and how they a
|
||||
Permissions in Formbricks are broadly handled using organization-level roles, which apply to all teams and projects in the organization. Users on a self-hosting and Enterprise plan, have access to team-level roles, which enable more granular permissions.
|
||||
|
||||
<Note>
|
||||
Access Roles is a feature of the **Enterprise Edition**. In the **Community Edition** and on the **Free**
|
||||
and **Startup** plan in the Cloud you can invite unlimited organization members as `Owner`.
|
||||
Access Roles is a feature of the **Enterprise Edition**. In the **Community Edition** and on the **Free** and **Startup** plan in the Cloud you can invite unlimited organization members as `Owner`.
|
||||
</Note>
|
||||
|
||||
Here are the different access permissions, ranked from highest to lowest access
|
||||
@@ -133,8 +132,7 @@ There are two ways to invite organization members: One by one or in bulk.
|
||||
/>
|
||||
|
||||
<Note>
|
||||
Access Roles is a feature of the **Enterprise Edition**. In the **Community Edition** and on the **Free**
|
||||
and **Startup** plan in the Cloud you can invite unlimited organization members as `Owners`.
|
||||
Access Roles is a feature of the **Enterprise Edition**. In the **Community Edition** and on the **Free** and **Startup** plan in the Cloud you can invite unlimited organization members as `Owners`.
|
||||
</Note>
|
||||
|
||||
Formbricks sends an email to the organization member with an invitation link. The organization member can accept the invitation or create a new account by clicking on the link.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import AddImageOrVideoToQuestionImage from "./images/add-image-or-video-to-question-image.webp";
|
||||
import AddImageOrVideoToQuestionVideo from "./images/add-image-or-video-to-question-video.webp";
|
||||
import AddImageOrVideoToQuestion from "./images/add-image-or-video-to-question.webp";
|
||||
@@ -29,6 +29,7 @@ Upload an image by clicking the upload icon or dragging the file:
|
||||
/>
|
||||
|
||||
## How to Add Videos
|
||||
|
||||
Toggle to add a video via link:
|
||||
|
||||
<MdxImage
|
||||
@@ -42,4 +43,6 @@ Toggle to add a video via link:
|
||||
|
||||
We support YouTube, Vimeo, and Loom URLs.
|
||||
|
||||
<Note>**YouTube Privacy Mode**: This option reduces tracking by converting YouTube URLs to no-cookie URLs. It only works with YouTube.</Note>
|
||||
<Note>
|
||||
**YouTube Privacy Mode**: This option reduces tracking by converting YouTube URLs to no-cookie URLs. It only works with YouTube.
|
||||
</Note>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import ActionCalculateOperators from "./images/action-calculate-operators.webp";
|
||||
import ActionCalculateValue from "./images/action-calculate-value.webp";
|
||||
import ActionCalculateVariables from "./images/action-calculate-variables.webp";
|
||||
@@ -38,8 +38,7 @@ Create complex survey logic with the Logic Editor. Use conditions, actions, and
|
||||
|
||||
<MdxImage src={AddLogic} alt="Add Logic" quality="100" className="max-w-full rounded-lg sm:max-w-3xl" />
|
||||
<Note>
|
||||
You can add multiple logic blocks to a survey. Logic blocks are executed in the order they are added. You
|
||||
can rearrange the order of logic blocks.
|
||||
You can add multiple logic blocks to a survey. Logic blocks are executed in the order they are added. You can rearrange the order of logic blocks.
|
||||
</Note>
|
||||
|
||||
2. **Add Conditions**: Add conditions to the logic block. Conditions are rules that determine when an action should be executed.
|
||||
@@ -87,8 +86,7 @@ Conditons can be based on:
|
||||
/>
|
||||
|
||||
<Note>
|
||||
- Conditions can be grouped. - Conditions can be combined using AND or OR operators. You can add multiple
|
||||
conditions to a logic block. Conditions are evaluated in the order they are added.
|
||||
- Conditions can be grouped. - Conditions can be combined using AND or OR operators. You can add multiple conditions to a logic block. Conditions are evaluated in the order they are added.
|
||||
</Note>
|
||||
|
||||
<MdxImage
|
||||
|
||||
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,48 @@
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
|
||||
import EmailCustomizationSettings from "./email-customization-card.webp";
|
||||
import EmailSample from "./email-sample.webp";
|
||||
import UpdatedLogo from "./updated-logo.webp";
|
||||
|
||||
export const metadata = {
|
||||
title: "Email Customization",
|
||||
description: "Customize the email that is sent to your users!",
|
||||
};
|
||||
|
||||
# Email Customization
|
||||
|
||||
Email customization is a white-label feature that allows you to customize the email that is sent to your users. You can upload a logo of your company and use it in the email.
|
||||
|
||||
<Note>
|
||||
This feature is a white-label feature. It is only available for users on paid plans or have an enterprise license.
|
||||
</Note>
|
||||
|
||||
## How to Upload a Logo
|
||||
|
||||
1. Go to the Organization Settings page.
|
||||
2. You will see a card called **Email Customization** under the **General** section.
|
||||
|
||||
<MdxImage
|
||||
src={EmailCustomizationSettings}
|
||||
alt="Email Customization Settings"
|
||||
quality="100"
|
||||
className="max-w-full rounded-lg sm:max-w-3xl"
|
||||
/>
|
||||
|
||||
3. Upload a logo of your company.
|
||||
4. Click on the **Save** button.
|
||||
|
||||
<MdxImage src={UpdatedLogo} alt="Updated Logo" quality="100" className="max-w-full rounded-lg sm:max-w-3xl" />
|
||||
|
||||
## Viewing the Logo in the Email
|
||||
|
||||
You can click on the **Send test email** button to get a test email with the logo.
|
||||
|
||||
<MdxImage src={EmailSample} alt="Email Sample" quality="100" className="max-w-full rounded-lg sm:max-w-3xl" />
|
||||
|
||||
<Note>Only the owner and managers of the organization can modify the logo.</Note>
|
||||
|
||||
## Use Cases
|
||||
|
||||
- **White-labeling**: You can use this feature to white-label your emails to your users.
|
||||
- **Branding**: You can use this feature to add your logo to your emails to increase brand recognition.
|
||||
|
After Width: | Height: | Size: 30 KiB |
@@ -1,4 +1,4 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
|
||||
import FilledHiddenFields from "./filled-hidden-fields.webp";
|
||||
import HiddenFieldResponses from "./hidden-field-responses.webp";
|
||||
@@ -74,6 +74,7 @@ https://formbricks.com/clin3dxja02k8l80hpwmx4bjy?screen=landing_page&job=Founder
|
||||
</Col>
|
||||
|
||||
### App & Website Surveys
|
||||
|
||||
For in-product surveys, you can set hidden fields in the response by adding them to the `formbricks.track` call:
|
||||
|
||||
<Col>
|
||||
@@ -106,4 +107,4 @@ These hidden fields will now be visible in the responses tab just like other fie
|
||||
|
||||
- **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](/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.
|
||||
- **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.
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -1,13 +1,12 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
|
||||
import StepOne from "./images/StepOne.webp";
|
||||
import StepThree from "./images/StepThree.webp";
|
||||
import StepTwo from "./images/StepTwo.webp";
|
||||
import StepOne from "./images/step-one.webp";
|
||||
import StepThree from "./images/step-three.webp";
|
||||
import StepTwo from "./images/step-two.webp";
|
||||
|
||||
export const metadata = {
|
||||
title: "Set a Maximum Number of Submissions for Surveys",
|
||||
description:
|
||||
"Limit the number of responses your survey can receive.",
|
||||
description: "Limit the number of responses your survey can receive.",
|
||||
};
|
||||
|
||||
# Limit by Number of Submissions
|
||||
@@ -20,7 +19,7 @@ Automatically close your survey after a specific number of responses with Formbr
|
||||
src={StepTwo}
|
||||
alt="Choose a link survey template"
|
||||
quality="100"
|
||||
className="max-w-full rounded-lg sm:max-w-3xl "
|
||||
className="max-w-full rounded-lg sm:max-w-3xl"
|
||||
/>
|
||||
- **Details**: Set a specific number of responses after which the survey automatically closes.
|
||||
- **Use Case**: Perfect for limited offers, exclusive surveys, or when you need a precise sample size for statistical significance.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { TellaVideo } from "@/components/TellaVideo";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import { TellaVideo } from "@/components/tella-video";
|
||||
|
||||
import Filters from "./filters.webp";
|
||||
import MetadataCard from "./metadata-card.webp";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
|
||||
import { ResponsiveVideo } from "@/components/ResponsiveVideo";
|
||||
import { ResponsiveVideo } from "@/components/responsive-video";
|
||||
import AddLanguageInSurvey from "./add-language-in-survey.webp";
|
||||
import AddLanguages from "./add-languages.webp";
|
||||
import EditMultiLang from "./edit-multi-lang.webp";
|
||||
@@ -137,8 +137,7 @@ Formbricks.init({
|
||||
</Col>
|
||||
|
||||
<Note>
|
||||
If a user has a language assigned, a survey has multi-language activate and it is missing a translation in
|
||||
the language of the user, the survey will not be displayed.
|
||||
If a user has a language assigned, a survey has multi-language activate and it is missing a translation in the language of the user, the survey will not be displayed.
|
||||
</Note>
|
||||
|
||||
2. That's it! Now, users with the language attribute set will see the survey in their preferred language. You can start collecting responses in multiple languages and filter them by language on the summary page.
|
||||
|
||||
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 18 KiB |
@@ -1,13 +1,13 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
|
||||
import StepEleven from "./images/StepEleven.webp";
|
||||
import StepNine from "./images/StepNine.webp";
|
||||
import StepTen from "./images/StepTen.webp";
|
||||
import StepEleven from "./images/step-eleven.webp";
|
||||
import StepNine from "./images/step-nine.webp";
|
||||
import StepTen from "./images/step-ten.webp";
|
||||
|
||||
import Doggo from "./images/Doggo.jpg";
|
||||
import HipsterLiving from "./images/HipsterLiving.jpg";
|
||||
import Mario from "./images/Mario.webp";
|
||||
import WindowsXp from "./images/WindowsXp.jpg";
|
||||
import Doggo from "./images/doggo.webp";
|
||||
import HipsterLiving from "./images/hipster-living.webp";
|
||||
import Mario from "./images/mario.webp";
|
||||
import WindowsXp from "./images/windows-xp.webp";
|
||||
|
||||
export const metadata = {
|
||||
title: "Overwrite Styling Theme on Individual Surveys",
|
||||
@@ -20,7 +20,7 @@ export const metadata = {
|
||||
Overwrite the global styling theme for individual surveys to create unique styles for each survey.
|
||||
|
||||
<Note>
|
||||
To set a styling theme for all surveys, please see the [Styling Theme](/core-features/global/styling-theme) manual.{" "}
|
||||
To set a styling theme for all surveys, please see the [Styling Theme](/core-features/global/styling-theme) manual.
|
||||
</Note>
|
||||
|
||||
### Overwrite Styling Theme
|
||||
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -1,6 +1,6 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
|
||||
import StepOne from "./images/StepOne.webp";
|
||||
import StepOne from "./images/step-one.webp";
|
||||
|
||||
export const metadata = {
|
||||
title: "Collect Partial Submissions with Formbricks",
|
||||
@@ -39,7 +39,7 @@ Formbricks provides detailed analytics for partial submissions, including a per-
|
||||
src={StepOne}
|
||||
alt="Choose a link survey template"
|
||||
quality="100"
|
||||
className="max-w-full rounded-lg sm:max-w-3xl "
|
||||
className="max-w-full rounded-lg sm:max-w-3xl"
|
||||
/>
|
||||
|
||||
### **Survey Summary Analytics**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import Address from "./images/address.webp";
|
||||
|
||||
#### Question Type
|
||||
@@ -20,17 +20,20 @@ The Address question type allows respondents to input their address details, inc
|
||||
/>
|
||||
|
||||
### Question
|
||||
|
||||
Provide a question to describe the address information you are requesting.
|
||||
|
||||
### Description
|
||||
|
||||
Optionally, add a description to guide the user.
|
||||
|
||||
### Toggle Fields
|
||||
You can choose to show and require any or all of the following fields in the form:
|
||||
- Address Line 1
|
||||
- Address Line 2
|
||||
- City
|
||||
- State
|
||||
- Zip Code
|
||||
- Country
|
||||
|
||||
You can choose to show and require any or all of the following fields in the form:
|
||||
|
||||
- Address Line 1
|
||||
- Address Line 2
|
||||
- City
|
||||
- State
|
||||
- Zip Code
|
||||
- Country
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import Consent from "./images/consent.webp";
|
||||
|
||||
#### Question Type
|
||||
@@ -11,6 +11,7 @@ The Consent card is used to obtain user agreement regarding a product, service,
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/orxp15pca6x2nfr3v8pttpwm" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={Consent}
|
||||
alt="Overview of Consent question type"
|
||||
@@ -19,10 +20,13 @@ The Consent card is used to obtain user agreement regarding a product, service,
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
A bold statement or question asking for user consent, displayed prominently at the top of the card.
|
||||
|
||||
### Description
|
||||
|
||||
A short explanation or additional context for the consent request, displayed below the title. The text can be formatted, and hyperlinks are allowed within the description.
|
||||
|
||||
### Checkbox
|
||||
At the bottom of the card, users can confirm their agreement by checking the box, indicating their consent to the question or statement above. The label for the checkbox is also editable.
|
||||
|
||||
At the bottom of the card, users can confirm their agreement by checking the box, indicating their consent to the question or statement above. The label for the checkbox is also editable.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import Contact from "./images/contact.webp";
|
||||
|
||||
#### Question Type
|
||||
@@ -11,6 +11,7 @@ The Contact Info question type allows respondents to provide their basic contact
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/z2zjoonfeythx5n6z5qijbsg" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={Contact}
|
||||
alt="Overview of Contact Info question type"
|
||||
@@ -29,8 +30,9 @@ Optionally, add a description to give additional context.
|
||||
### Toggle Fields
|
||||
|
||||
You can choose to show and require any or all of the following fields:
|
||||
- First Name
|
||||
- Last Name
|
||||
- Email
|
||||
- Phone Number
|
||||
- Company
|
||||
|
||||
- First Name
|
||||
- Last Name
|
||||
- Email
|
||||
- Phone Number
|
||||
- Company
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import Date from "./images/date.webp";
|
||||
|
||||
#### Question Type
|
||||
@@ -11,6 +11,7 @@ The Date question type allows respondents to provide a date, such as when they a
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/rk844spc8ffls25vzkxzzhse" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={Date}
|
||||
alt="Overview of Date question type"
|
||||
@@ -19,14 +20,17 @@ The Date question type allows respondents to provide a date, such as when they a
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
Add a clear title to inform the respondent what date you are asking for.
|
||||
|
||||
### Description
|
||||
|
||||
Provide an optional description with further instructions.
|
||||
|
||||
### Date Format
|
||||
Choose from multiple date formats for the input:
|
||||
- MM-DD-YYYY
|
||||
- DD-MM-YYYY
|
||||
- YYYY-MM-DD
|
||||
|
||||
Choose from multiple date formats for the input:
|
||||
|
||||
- MM-DD-YYYY
|
||||
- DD-MM-YYYY
|
||||
- YYYY-MM-DD
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import FileUpload from "./images/file-upload.webp";
|
||||
|
||||
#### Questions Type
|
||||
@@ -11,6 +11,7 @@ The File Upload question type allows respondents to upload files related to your
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/oo4e6vva48w0trn01ht8krwo" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={FileUpload}
|
||||
alt="Overview of Fill Upload question type"
|
||||
@@ -19,16 +20,21 @@ The File Upload question type allows respondents to upload files related to your
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
Add a clear title that informs the respondent about the purpose of the file upload.
|
||||
|
||||
### Description
|
||||
|
||||
Provide an optional description to give respondents more details or instructions about what files they need to upload.
|
||||
|
||||
### Allow Multiple Files
|
||||
|
||||
Enable this option to allow respondents to upload multiple files at once.
|
||||
|
||||
### Max File Size
|
||||
|
||||
You can set a maximum file size limit, and an input box will appear to specify the size in MB.
|
||||
|
||||
### File Type Restrictions
|
||||
You can restrict the allowed file types. An input box will appear where you can specify the file formats, such as `.pdf`, `.jpg`, `.docx`, etc.
|
||||
|
||||
You can restrict the allowed file types. An input box will appear where you can specify the file formats, such as `.pdf`, `.jpg`, `.docx`, etc.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import FreeText from "./images/free-text.webp";
|
||||
|
||||
export const metadata = {
|
||||
@@ -16,6 +16,7 @@ Free text questions allow respondents to enter a custom answer. Displays a title
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/cm2b2eftv000012b0l3htbu0a" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={FreeText}
|
||||
alt="Overview of Free Text question type"
|
||||
@@ -24,12 +25,15 @@ Free text questions allow respondents to enter a custom answer. Displays a title
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
Add a clear title to inform the respondent what information you are asking for.
|
||||
|
||||
### Description
|
||||
|
||||
Provide an optional description with further instructions.
|
||||
|
||||
### Placeholder
|
||||
|
||||
Specify a placeholder text to display in the input field.
|
||||
|
||||
### Input Type
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import Matrix from "./images/matrix.webp";
|
||||
|
||||
#### Question Type
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import MultiSelect from "./images/multi-select.webp";
|
||||
|
||||
export const metadata = {
|
||||
@@ -16,6 +16,7 @@ Multi select questions allow respondents to select several answers from a list.
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/jhyo6lwzf6eh3fyplhlp7h5f" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={MultiSelect}
|
||||
alt="Overview of Multi Select question type"
|
||||
@@ -24,13 +25,15 @@ Multi select questions allow respondents to select several answers from a list.
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
Add a clear title to inform the respondent what information you are asking for.
|
||||
|
||||
### Description
|
||||
|
||||
Provide an optional description with further instructions.
|
||||
|
||||
### Options
|
||||
|
||||
Define the options shown in the list. These represent the items for which users will select.
|
||||
|
||||
Other than the fact that respondents can select multiple options, multi select questions are similar to [single select](/global/question-types/single-select) questions.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import NetPromoterScore from "./images/net-promoter-score.webp";
|
||||
|
||||
#### Question Type
|
||||
@@ -11,6 +11,7 @@ Net Promoter Score questions allow respondents to rate a question on a scale fro
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/vqmpasmnt5qcpsa4enheips0" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={NetPromoterScore}
|
||||
alt="Overview of Net Promoter Score question type"
|
||||
@@ -19,13 +20,17 @@ Net Promoter Score questions allow respondents to rate a question on a scale fro
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
Add a clear title to inform the respondent what information you are asking for.
|
||||
|
||||
### Description
|
||||
|
||||
Provide an optional description with further instructions.
|
||||
|
||||
### Labels
|
||||
|
||||
Add labels for the lower and upper bounds of the score. The default is "Not at all likely" and "Extremely likely".
|
||||
|
||||
### Add color coding
|
||||
Add color coding to the score. This will show a color bar above the score.
|
||||
|
||||
Add color coding to the score. This will show a color bar above the score.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import PictureSelection from "./images/picture-selection.webp";
|
||||
|
||||
export const metadata = {
|
||||
@@ -16,6 +16,7 @@ Picture selection questions allow respondents to select one or more images from
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/xtgmwxlk7jxxr4oi6ym7odki" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={PictureSelection}
|
||||
alt="Overview of Picture Selection question type"
|
||||
@@ -24,13 +25,17 @@ Picture selection questions allow respondents to select one or more images from
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
Add a clear title to inform the respondent what information you are asking for.
|
||||
|
||||
### Description
|
||||
|
||||
Provide an optional description with further instructions.
|
||||
|
||||
### Images
|
||||
|
||||
Images can be uploaded via click or drag and drop. At least two images are required.
|
||||
|
||||
### Allow Multi Select
|
||||
This option allows user to select more than one image.
|
||||
|
||||
This option allows user to select more than one image.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import Ranking from "./images/ranking.webp";
|
||||
|
||||
#### Question Type
|
||||
@@ -11,6 +11,7 @@ Ranking questions let respondents select options in order from 1 to the total nu
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/z6s84x9wbyk0yqqtfaz238px" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={Ranking}
|
||||
alt="Overview of Ranking question type"
|
||||
@@ -19,14 +20,18 @@ Ranking questions let respondents select options in order from 1 to the total nu
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
Add a clear title to inform the respondent what information you are asking for.
|
||||
|
||||
### Description
|
||||
|
||||
Provide an optional description with further instructions.
|
||||
|
||||
### Options
|
||||
|
||||
You need to add at least two options so that users can rearrange them in numerical order based on their selection.
|
||||
|
||||
### Select ordering
|
||||
|
||||
- Keep current order: This will keep the order of options the same for all respondents.
|
||||
- Randomize all: This will randomize the options for each respondent.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import Rating from "./images/rating.webp";
|
||||
|
||||
export const metadata = {
|
||||
@@ -16,6 +16,7 @@ Rating questions allow respondents to rate questions on a scale. Displays a titl
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/cx7u4n6hwvc3nztuk4vdezl9" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={Rating}
|
||||
alt="Overview of Rating question type"
|
||||
@@ -24,16 +25,21 @@ Rating questions allow respondents to rate questions on a scale. Displays a titl
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
Add a clear title to inform the respondent what information you are asking for.
|
||||
|
||||
### Description
|
||||
|
||||
Provide an optional description with further instructions.
|
||||
|
||||
### Scale
|
||||
|
||||
Select the icon to be used for the rating scale. The options include: stars, numbers or smileys. The default is stars.
|
||||
|
||||
### Range
|
||||
|
||||
Select the range of the rating scale. the options include: 3, 4, 5, 7 or 10. The default is 5.
|
||||
|
||||
### Labels
|
||||
Add labels for the lower and upper bounds of the rating scale. The default is "Not good" and "Very good".
|
||||
|
||||
Add labels for the lower and upper bounds of the rating scale. The default is "Not good" and "Very good".
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import ScheduleCall from "./images/schedule-call.webp";
|
||||
|
||||
#### Question Type
|
||||
@@ -11,6 +11,7 @@ The Schedule A Meeting question type allows respondents to book a meeting by sel
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/hx08x27c2aghywh57rroe6fi" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={ScheduleCall}
|
||||
alt="Overview of Schedule question type"
|
||||
@@ -19,13 +20,17 @@ The Schedule A Meeting question type allows respondents to book a meeting by sel
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
Add a clear title to inform the respondent what information you are asking for.
|
||||
|
||||
### Description
|
||||
|
||||
Provide an optional description with further instructions.
|
||||
|
||||
### Cal.com Username/Event
|
||||
|
||||
Add an input box where users can enter their [`cal.com`](https://cal.com/) username and event URL (e.g., `username/event`).
|
||||
|
||||
### Custom Hostname (Optional)
|
||||
Enable an input box for adding a custom hostname, which is necessary if using a self-hosted instance of [`cal.com`](https://cal.com/docs/self-hosting/installation).
|
||||
|
||||
Enable an input box for adding a custom hostname, which is necessary if using a self-hosted instance of [`cal.com`](https://cal.com/docs/self-hosting/installation).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import SingleSelect from "./images/single-select.webp";
|
||||
|
||||
export const metadata = {
|
||||
@@ -16,6 +16,7 @@ Single select questions allow respondents to select one answer from a list. Disp
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/wybd3v3cxpdfve4472fu3lhi" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={SingleSelect}
|
||||
alt="Overview of Single Select question type"
|
||||
@@ -24,12 +25,15 @@ Single select questions allow respondents to select one answer from a list. Disp
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
Add a clear title to inform the respondent what information you are asking for.
|
||||
|
||||
### Description
|
||||
|
||||
Provide an optional description with further instructions.
|
||||
|
||||
### Options
|
||||
|
||||
The list of answers the respondent can choose from.
|
||||
|
||||
### Additional Actions
|
||||
@@ -41,4 +45,4 @@ The list of answers the respondent can choose from.
|
||||
- Order dropdown: Allows you to choose the order in which the options are displayed.
|
||||
- Keep current order: Options will be displayed in the order you added them.
|
||||
- Randomize all: Options will be displayed in a random order.
|
||||
- Randomize all except last option: Options will be displayed in a random order, except for the last one.
|
||||
- Randomize all except last option: Options will be displayed in a random order, except for the last one.
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -1,6 +1,6 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import StatementCTA from "./images/statement-CTA.webp";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import StatementCTA from "./images/statement-cta.webp";
|
||||
|
||||
#### Question Type
|
||||
|
||||
@@ -11,6 +11,7 @@ The Statement question type allows you to display descriptive information in you
|
||||
<SurveyEmbed surveyUrl="https://app.formbricks.com/s/k3p7r7riyy504u4zziqat8zj" />
|
||||
|
||||
## Elements
|
||||
|
||||
<MdxImage
|
||||
src={StatementCTA}
|
||||
alt="Overview of Statement question type"
|
||||
@@ -19,11 +20,14 @@ The Statement question type allows you to display descriptive information in you
|
||||
/>
|
||||
|
||||
### Title
|
||||
|
||||
This is the main question or heading that appears at the top of the card.
|
||||
|
||||
### Description
|
||||
|
||||
A brief note or instruction displayed under the title, typically used to provide context or instructions for the next step.
|
||||
|
||||
### Button Options
|
||||
|
||||
- Button to continue in survey: This will continue respondent with the survey, form or fillups.
|
||||
- Button to link to external URL: Selecting this option will open-up URL input box below when us set URL the button will redirect to your setted link.
|
||||
|
||||
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -1,19 +1,21 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import SurveyEmbed from "@/components/SurveyEmbed";
|
||||
import StepOne from "./images/StepOne.webp";
|
||||
import StepThree from "./images/StepThree.webp";
|
||||
import StepTwo from "./images/StepTwo.webp";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
import SurveyEmbed from "@/components/survey-embed";
|
||||
import StepOne from "./images/step-one.webp";
|
||||
import StepThree from "./images/step-three.webp";
|
||||
import StepTwo from "./images/step-two.webp";
|
||||
|
||||
export const metadata = {
|
||||
title: "Recall Data in Formbricks Surveys",
|
||||
description:
|
||||
"Personalize your surveys by dynamically inserting data from URL parameters or previous answers into questions and descriptions. The Recall Data feature helps create engaging, adaptive survey experiences tailored to each respondent."};
|
||||
"Personalize your surveys by dynamically inserting data from URL parameters or previous answers into questions and descriptions. The Recall Data feature helps create engaging, adaptive survey experiences tailored to each respondent.",
|
||||
};
|
||||
|
||||
# Recall Data
|
||||
|
||||
Personalize your surveys by dynamically inserting data from URL parameters or previous answers into questions and descriptions. The Recall Data feature helps create engaging, adaptive survey experiences tailored to each respondent.
|
||||
|
||||
## Recall Sources
|
||||
|
||||
You can recall data from the following sources:
|
||||
|
||||
- From a previous question
|
||||
@@ -23,8 +25,7 @@ You can recall data from the following sources:
|
||||
## Recalling from a previous question
|
||||
|
||||
<Note>
|
||||
The recall functionality is disabled on the first question of the survey since there’s no preceding question
|
||||
to recall data from.
|
||||
The recall functionality is disabled on the first question of the survey since there’s no preceding question to recall data from.
|
||||
</Note>
|
||||
|
||||
### **Pre-requisite**
|
||||
@@ -35,7 +36,7 @@ Ensure the answer you wish to recall precedes the question in which it will be r
|
||||
src={StepThree}
|
||||
alt="Survey setup example with link survey template"
|
||||
quality="100"
|
||||
className="max-w-full rounded-lg sm:max-w-3xl "
|
||||
className="max-w-full rounded-lg sm:max-w-3xl"
|
||||
/>
|
||||
|
||||
### **Step 1: Recall Data**
|
||||
@@ -46,7 +47,7 @@ Type **`@`** in the question or description field where you want to insert a rec
|
||||
src={StepTwo}
|
||||
alt="Dropdown menu for recalling data in survey"
|
||||
quality="100"
|
||||
className="max-w-full rounded-lg sm:max-w-3xl "
|
||||
className="max-w-full rounded-lg sm:max-w-3xl"
|
||||
/>
|
||||
|
||||
### **Step 2: Set a Fallback**
|
||||
@@ -57,10 +58,11 @@ To ensure the survey remains coherent when a response is missing (or the questio
|
||||
src={StepOne}
|
||||
alt="Setting fallback option in survey question"
|
||||
quality="100"
|
||||
className="max-w-full rounded-lg sm:max-w-3xl "
|
||||
className="max-w-full rounded-lg sm:max-w-3xl"
|
||||
/>
|
||||
|
||||
## Recalling from the URL
|
||||
|
||||
1. Create a hidden field, [here is how →](/docs/global/hidden-fields)
|
||||
2. Use the `@` symbol in a question or description to recall the value of the hidden field
|
||||
3. Set a fallback in case the hidden field is not being filled by a URL parameter
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -1,13 +1,12 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
|
||||
import StepOne from "./images/StepOne.webp";
|
||||
import StepThree from "./images/StepThree.webp";
|
||||
import StepTwo from "./images/StepTwo.webp";
|
||||
import StepOne from "./images/step-one.webp";
|
||||
import StepThree from "./images/step-three.webp";
|
||||
import StepTwo from "./images/step-two.webp";
|
||||
|
||||
export const metadata = {
|
||||
title: "Schedule Start & End Dates for Surveys",
|
||||
description:
|
||||
"Automatically release and close surveys based on specific dates.",
|
||||
description: "Automatically release and close surveys based on specific dates.",
|
||||
};
|
||||
|
||||
# Schedule Start & End Dates
|
||||
@@ -24,7 +23,7 @@ Configure your surveys to open and close based on specific criteria. Here’s ho
|
||||
src={StepOne}
|
||||
alt="Choose a link survey template"
|
||||
quality="100"
|
||||
className="max-w-full rounded-lg sm:max-w-3xl "
|
||||
className="max-w-full rounded-lg sm:max-w-3xl"
|
||||
/>
|
||||
|
||||
- **Details**: Choose the date and time when the survey should become available to respondents. All times follow UTC timezone.
|
||||
@@ -38,11 +37,11 @@ Configure your surveys to open and close based on specific criteria. Here’s ho
|
||||
src={StepThree}
|
||||
alt="Choose a link survey template"
|
||||
quality="100"
|
||||
className="max-w-full rounded-lg sm:max-w-3xl "
|
||||
className="max-w-full rounded-lg sm:max-w-3xl"
|
||||
/>
|
||||
- **Details**: Define a specific date and time for the survey to close. This also follows UTC timezone. - **Use
|
||||
Case**: Essential for surveys linked to time-bound events or studies where data collection needs to end at a specific
|
||||
point.
|
||||
- **Details**: Define a specific date and time for the survey to close. This also follows UTC timezone. -
|
||||
**Use Case**: Essential for surveys linked to time-bound events or studies where data collection needs to end
|
||||
at a specific point.
|
||||
|
||||
### **Summary**
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
|
||||
import StepOne from "./images/1-publish-to-web.webp";
|
||||
import StepTwo from "./images/2-warning-publish.webp";
|
||||
@@ -6,8 +6,7 @@ import StepThree from "./images/3-share-link.webp";
|
||||
|
||||
export const metadata = {
|
||||
title: "Shareable Dashboards",
|
||||
description:
|
||||
"Create shareable links to dashboards of specific surveys.",
|
||||
description: "Create shareable links to dashboards of specific surveys.",
|
||||
};
|
||||
|
||||
# Shareable Dashboards
|
||||
|
||||
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
@@ -1,7 +1,7 @@
|
||||
import { MdxImage } from "@/components/MdxImage";
|
||||
import { MdxImage } from "@/components/mdx-image";
|
||||
|
||||
import StepOne from "./images/StepOne.webp";
|
||||
import StepTwo from "./images/StepTwo.webp";
|
||||
import StepOne from "./images/step-one.webp";
|
||||
import StepTwo from "./images/step-two.webp";
|
||||
|
||||
export const metadata = {
|
||||
title: "Show Survey to % of Users",
|
||||
@@ -14,8 +14,7 @@ export const metadata = {
|
||||
To target specific segments of your audience or manage survey exposure, Formbricks allows you to display surveys to only a percentage of your targeted users.
|
||||
|
||||
<Note>
|
||||
This feature is applicable for website surveys and app surveys, where managing participant engagement and
|
||||
response volume is crucial.
|
||||
This feature is applicable for website surveys and app surveys, where managing participant engagement and response volume is crucial.
|
||||
</Note>
|
||||
|
||||
## **Enabling Percentage-Based Visibility**
|
||||
@@ -34,7 +33,7 @@ Set up this feature to control how many users see your survey, using a simple sl
|
||||
src={StepOne}
|
||||
alt="Choose a link survey template"
|
||||
quality="100"
|
||||
className="max-w-full rounded-lg sm:max-w-3xl "
|
||||
className="max-w-full rounded-lg sm:max-w-3xl"
|
||||
/>
|
||||
|
||||
- Select **`Survey Trigger`** from the menu options.
|
||||
@@ -51,12 +50,11 @@ Set up this feature to control how many users see your survey, using a simple sl
|
||||
src={StepTwo}
|
||||
alt="Choose a link survey template"
|
||||
quality="100"
|
||||
className="max-w-full rounded-lg sm:max-w-3xl "
|
||||
className="max-w-full rounded-lg sm:max-w-3xl"
|
||||
/>
|
||||
|
||||
<Note>
|
||||
Please note that this feature operates based on mathematical probabilistic functions, which may result in
|
||||
slight variations in the exact percentage of users who see the survey.{" "}
|
||||
Please note that this feature operates based on mathematical probabilistic functions, which may result in slight variations in the exact percentage of users who see the survey.
|
||||
</Note>
|
||||
|
||||
### **Example Usage**
|
||||
|
||||
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |