This approach offers a number of advantages, including:
- Version control: Survey files can be stored in a Github repository, which makes it easy to track changes and collaborate with others.
- Reproducibility: Survey files can be easily shared and reproduced, making it easy to reuse surveys or create variations of existing surveys.
- Automation: Survey files can be used to automate the creation and deployment of surveys, which can save time and effort.
Formulosity uses human-readable declarative language YAML.
- Management API
- Survey UI: for end users (respondents)
- Console UI: manage surveys
- YAML survey configuration
- Basic question types
- Default theme
- Custom themes support
- Personalized options: intro, outro, etc.
- Cookie/IP duplicate response protection
- Admin user authentication
- Different database options: SQLite and Postgres
- Continue where you left off
- Advanced validation rules
- Detect survey changes in real time
- Export responses in UI or via API
- Advanced question types
- Pipe answers into the following questions
Each directory in SURVEYS_DIR
is a survey. You can configure the source of your surveys by setting different SURVEYS_DIR
env var.
surveys/
├── survey1/
│ ├── metadata.yaml
│ ├── questions.yaml
│ ├── security.yaml
│ ├── variables.yaml
│ └── ...
└── survey2/
├── metadata.yaml
├── questions.yaml
└── ...
To get started, check out the ./api/surveys
folder with multiple examples.
This file is required! The file consists of a YAML object with specific properties describing the survey.
- title: This is the main title displayed to users at the beginning of the survey.
- theme: This specifies the visual theme applied to the survey. Currently supported themes are: default.
- intro: This text appears as an introduction before the first question.
- outro: This text appears as a conclusion after the last question.
title: Survey Title
theme: default # or custom
intro: |
This is the introduction to the survey.
It can be multiple lines long.
outro: |
Thank you for taking the survey.
Your feedback is important to us.
This file is required! The file consists of a list of questions, each defined as a YAML object with specific properties.
- type: This specifies the type of question being asked.
- id: This provides a unique identifier for the question. It is useful for referencing specific questions in branching logic or data analysis. IDs must be unique across all questions in the survey.
- label: This is the text displayed to the user as the question itself.
- description: This provides additional information about the question for the user, such as clarification or instructions.
- options: This list defines the available answer choices for question types like
single-choice
,multiple-choice
andranking
. - optionsFromVariable: This property references a variable defined in a separate variables.yaml file. The variable should contain a list of options to be used for the question. This allows for reusability and centralized management of option lists.
- validation: This property is used to define validation rules for specific question types.
questions:
- type: single-choice
id: question1 # optional ID, must be unique across all questions
label: What is the capital of Germany?
description: You can select multiple options
optionsFromVariable: german-city-options # defined in variables.yaml
options:
- Berlin
- Munich
- Paris
- London
- Hamburg
- Cologne
validation:
min: 1
max: 3
This file is optional. The file consists of a YAML object with specific properties for survey security settings.
- duplicateProtection: This property defines how the platform handles duplicate responses from the same user.
duplicateProtection: cookie # cookie | ip
This file is optional. The file consists of a list of variables, each defined as a YAML object with specific properties.
- id: This unique identifier references the variable within questions. IDs must be unique across all variables defined in the file.
- type: This specifies the type of data stored in the variable. Currently supported types are: list.
variables:
- id: german-city-options # must be unique
type: list
options:
- Berlin
- Munich
- Hamburg
- Cologne
Prompts users for a brief written answer.
- type: short-text
label: What is the capital of Germany?
# set min/max characters
validation:
min: 10
max: 100
Prompts users for a detailed written answer.
- type: long-text
label: What is the capital of Germany?
# set min/max characters
validation:
min: 10
max: 100
Presents a question with only one correct answer from a list of options.
- type: single-choice
label: What is the capital of Germany?
options:
- Berlin
- Munich
- Paris
- London
- Hamburg
- Cologne
Presents a question where users can select multiple answers (with limitations). You can customize the minimum and maximum allowed selections in the validation section.
- type: multiple-choice
label: Which of the following are cities in Germany?
description: You can select multiple options
validation:
min: 1
max: 3
options:
- Berlin
- Munich
- Paris
- London
- Hamburg
- Cologne
Asks users to enter a specific date.
- type: date
label: When was the Berlin Wall built?
Presents a scale for users to rate something on a predefined range.
- type: rating
label: How much do you like Berlin?
min: 1
max: 5
Asks users to rank options based on a given criteria.
- type: ranking
label: Rank the following cities by population
optionsFromVariable: german-city-options
Presents a question where users can only answer "yes" or "no".
- type: yes-no
label: Is Berlin the capital of Germany?
Prompts user to enter their email
- type: email
label: Please enter your email.
Prompts user to upload their file based on a given formats and maximum upload size.
- type: file
label: Upload a Berlin Image
validation:
formats:
- .jpg
- .png
max_size_bytes: 5*1024*1024 # 5 MB
Responses can be shown in the UI and exported as a JSON. Alternatively you can use REST API to get survey resposnes:
curl -XGET \
http://localhost:9900/app/surveys/{SURVEY_ID}/sessions?limit=100&offset=0&sort_by=created_at&order=desc
Where {SURVEY_ID}
id the UUID of a given survey.
docker-compose up -d --build
And you should be able to access the UI on localhost:3000 (default basic auth: user:pass
).
You can deploy individual services to any cloud provider or self host them.
- Go backend. It's packaged as a Docker container and can be deployed anywhere.
- Next.js frontend. It's also packaged as a Docker container, but also can be deployed to Vercel for example.
- [Optional] Postgres database. You can use managed Postgres services or deploy it yourself.
API:
DATABASE_TYPE
-sqlite
orpostgres
DATABASE_URL
- Postgres or SQLite connection stringSURVEYS_DIR
- Directory with surveys, e.g./root/surveys
. It's suggested to use mounted volume for this directory.UPLOADS_DIR
- Directory for uploading files from the survey forms.
UI:
CONSOLE_API_ADDR
- Public address of the Go backend. Need to be accessible from the browser.CONSOLE_API_ADDR_INTERNAL
- Internal address of the Go backend, e.g.http://api:8080
(could be the same asCONSOLE_API_ADDR
).IRON_SESSION_SECRET
- Secret for session encryptionHTTP_BASIC_AUTH
- Format:user:pass
for basic auth (optional)
- Backend: Go, (Postgres or SQLite)
- UI: Next.js, Tailwind CSS
Make sure to install go-migrate first.
cd api
migrate create -dir migrations/postgres -ext sql -seq name
migrate create -dir migrations/sqlite -ext sql -seq name
cd api
make test
Pull requests, bug reports, and all other forms of contribution are welcomed and highly encouraged!