Technical docs (#553)
* WIP * Working on configuration * wip * Finished docs * Self hosted comparison + more links
247
README.md
|
|
@ -20,244 +20,37 @@
|
|||
<a href="https://console.algora.io/org/OpnForm/bounties?status=completed"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fconsole.algora.io%2Fapi%2Fshields%2FOpnForm%2Fbounties%3Fstatus%3Dcompleted" alt="Rewarded Bounties"></a>
|
||||
</p>
|
||||
|
||||
> An open-source form builder. It's an alternative to products like Typeform, JotForm, Tally etc.
|
||||
OpnForm is an open-source form builder.
|
||||
|
||||
## Features
|
||||
## Get Started
|
||||
|
||||
- No-code form builder, with infinite number of fields & submissions
|
||||
- Text inputs, Date inputs, URL inputs, Phone inputs, Email inputs, Checkboxes, Select and Multi-Select inputs, Number Inputs, Star-ratings, File uploads & more
|
||||
- Embed anywhere (on your website, in your Notion page, etc)
|
||||
- Email notifications (for both form owner & form respondents)
|
||||
- Hidden fields
|
||||
- Form passwords
|
||||
- URL form pre-fill
|
||||
- Slack integration
|
||||
- Webhooks
|
||||
- Form logic
|
||||
- Customize colors, add images or even some custom code
|
||||
- Captcha form protection
|
||||
- Form closing date
|
||||
- Limit the number of submissions allowed
|
||||
The easiest way to get started with OpnForm is to sign up for our [managed service in the Cloud](https://opnform.com/). You get support, backups, upgrades, and more. Your data is safe and secure, and you don't need to worry about maintenance or infrastructure. Check out our quick overview of [cloud vs self-hosting](https://docs.opnform.com/deployment/cloud-vs-self-hosting).
|
||||
|
||||
And much more!
|
||||
## Key Features
|
||||
|
||||
## Bounties
|
||||
- 🚀 No-code builder with unlimited forms & submissions
|
||||
- 📝 Various input types: Text, Date, URL, File uploads & much more
|
||||
- 🌐 Embed anywhere
|
||||
- 📧 Email notifications
|
||||
- 💬 Integrations (Slack, Webhooks, Discord)
|
||||
- 🧠 Form logic & customization
|
||||
- 🛡️ Captcha protection
|
||||
- 📊 Form analytics
|
||||
|
||||
Get paid for contributing to OpnForm! Here are our open bounties:
|
||||
For a complete list of features and detailed documentation, visit our [Technical Documentation](https://docs.opnform.com).
|
||||
|
||||
<a href="https://console.algora.io/org/OpnForm/bounties?status=open">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://console.algora.io/api/og/OpnForm/bounties.png?p=0&status=open&theme=dark">
|
||||
<img alt="Bounties of OpnForm" src="https://console.algora.io/api/og/OpnForm/bounties.png?p=0&status=open&theme=light">
|
||||
</picture>
|
||||
</a>
|
||||
## Quick Start
|
||||
|
||||
## Getting started with OpnForm
|
||||
The easiest way to get started with OpnForm is through our [official managed service in the Cloud](https://opnform.com/).
|
||||
|
||||
The easiest way to get started with OpnForm is with the [official managed service in the Cloud](https://opnform.com/).
|
||||
For self-hosted installations, please refer to our [Deployment Guides](https://docs.opnform.com/deployment). For detailed instructions on setting up a local environment, check out our [Local Deployment Documentation](https://docs.opnform.com/deployment/local-deployment).
|
||||
|
||||
It takes 1 minute to try out the builder for free. You'll have high availability, backups, security, and maintenance all managed for you.
|
||||
## Support & Community
|
||||
|
||||
### Requirements
|
||||
If you need help or have questions, please join our [Discord community](https://discord.gg/YTSjU2a9TS). For more information and assistance, check out the following resources:
|
||||
|
||||
- PHP >= 8.0
|
||||
- MySQL/MariaDB or PostgreSQL
|
||||
- Node.js and NPM/Yarn/... to compile assets
|
||||
|
||||
## Installation
|
||||
|
||||
### Environment Setup
|
||||
|
||||
Before you can run the application, you need to set up the environment variables. We have provided a script that will automate the process of creating your `.env` files from the provided examples.
|
||||
|
||||
Follow these steps to set up your environment:
|
||||
|
||||
1. Make sure you have `openssl` installed, as it is required by the setup script to generate secure keys.
|
||||
|
||||
2. Run the setup script from the root of the project:
|
||||
|
||||
```bash
|
||||
chmod +x ./scripts/setup-env.sh
|
||||
./scripts/setup-env.sh
|
||||
```
|
||||
|
||||
**If you are using Docker** and want to prepare a Docker-specific environment, run the script with the `--docker` flag:
|
||||
|
||||
```bash
|
||||
./scripts/setup-env.sh --docker
|
||||
```
|
||||
|
||||
3. After running the script, review the `.env` and `client/.env` files to ensure all settings are correct for your environment.
|
||||
|
||||
Remember to never commit your `.env` files to version control. They should be kept private as they contain sensitive information.
|
||||
|
||||
### Docker Installation 🐳
|
||||
|
||||
OpnForm can be easily set up using Docker. Pre-built images are available on Docker Hub, which is the recommended method for most users.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- Docker
|
||||
- Docker Compose
|
||||
|
||||
#### Quick Start
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```
|
||||
git clone https://github.com/JhumanJ/OpnForm.git
|
||||
cd OpnForm
|
||||
```
|
||||
|
||||
2. Set up environment files by running the provided setup script. For detailed instructions, refer to the [Environment Setup](#environment-setup) section above:
|
||||
|
||||
```bash
|
||||
./scripts/setup-env.sh --docker
|
||||
```
|
||||
|
||||
3. Start the application:
|
||||
|
||||
```
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
4. Access OpnForm at http://localhost
|
||||
|
||||
> 🌐 **Server Deployment Note**: When deploying to a server, configure the app URLs in both `.env` and `client/.env` files. Set `APP_URL` in `.env`, and both `NUXT_PUBLIC_APP_URL` & `NUXT_PUBLIC_API_BASE` in `client/.env`.
|
||||
|
||||
#### Customization
|
||||
|
||||
- **Environment Variables**: Modify `.env` and `client/.env` files to customize your setup. For example, to enable email features, configure a [supported mail driver](https://laravel.com/docs/11.x/mail) in the `.env` file.
|
||||
|
||||
#### Upgrading
|
||||
|
||||
1. Check the upgrade instructions for your target version in the documentation.
|
||||
2. Update your `docker-compose.yml` file if necessary.
|
||||
3. Apply changes:
|
||||
```
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
#### Initial Login
|
||||
|
||||
After installation, use these credentials to access the admin panel:
|
||||
|
||||
- Email: `admin@opnform.com`
|
||||
- Password: `password`
|
||||
|
||||
⚠️ Change these credentials immediately after your first login.
|
||||
|
||||
Note: Public registration is disabled in the self-hosted version. Use the admin account to invite additional users.
|
||||
|
||||
#### Building from Source
|
||||
|
||||
For development or customization, you can build the Docker images locally:
|
||||
|
||||
1. Build the images:
|
||||
|
||||
```
|
||||
docker build -t opnform-ui:local -f docker/Dockerfile.client .
|
||||
docker build -t opnform-api:local -f docker/Dockerfile.api .
|
||||
```
|
||||
|
||||
2. Create a docker-compose override file:
|
||||
|
||||
```
|
||||
touch docker-compose.override.yml
|
||||
```
|
||||
|
||||
Edit the `docker-compose.override.yml` file to use your locally built images:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
api:
|
||||
image: opnform-api:local
|
||||
ui:
|
||||
image: opnform-ui:local
|
||||
api-worker:
|
||||
image: opnform-api:local
|
||||
```
|
||||
|
||||
3. Start the application:
|
||||
```
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
This method allows you to make changes to the source code and rebuild the images as needed.
|
||||
|
||||
#### Clearing all resources
|
||||
|
||||
To completely remove all Docker containers, networks, and volumes created by `docker-compose` and also remove all images used by these services, you can use the following command:
|
||||
|
||||
```bash
|
||||
docker-compose down -v --rmi all
|
||||
```
|
||||
|
||||
### Using Laravel Valet
|
||||
|
||||
This section explains how to get started locally with the project. It's most likely relevant if you're trying to work on the project.
|
||||
First, let's work with the codebase and its dependencies.
|
||||
|
||||
```bash
|
||||
# Get the code!
|
||||
git clone git@github.com:JhumanJ/OpnForm.git && cd OpnForm
|
||||
|
||||
# Install PHP dependencies
|
||||
composer install
|
||||
|
||||
# Install JS dependencies
|
||||
cd client && npm install
|
||||
|
||||
# Compile assets (see the scripts section in package.json)
|
||||
npm run dev # or build
|
||||
```
|
||||
|
||||
Now, we can configure Laravel. We just need to prepare some vars in our `.env` file, just create it with `cp .env.example .env` then open it!
|
||||
|
||||
Configure the desired database in the `DATABASE_` section. You can fine tune your installation on the [laravel documentation](https://laravel.com/docs/9.x).
|
||||
|
||||
Run these artisan commands:
|
||||
|
||||
```bash
|
||||
# Generate needed secrets 🙈
|
||||
php artisan key:generate
|
||||
php artisan jwt:secret # and select yes!
|
||||
|
||||
# Creates DB schemas
|
||||
php artisan migrate
|
||||
```
|
||||
|
||||
Now, create an S3 bucket (or equivalent). Create an IAM user with access to this bucket, fill the environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_DEFAULT_REGION`, `AWS_BUCKET`. In your AWS bucket permissions, add the following under "Cross-origin resource sharing (CORS)":
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"AllowedHeaders": ["*"],
|
||||
"AllowedMethods": ["PUT", "POST", "GET", "DELETE"],
|
||||
"AllowedOrigins": ["*"],
|
||||
"ExposeHeaders": []
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
🎉 Done! Enjoy your personal OpnForm instance at: [http://opnform.test](http://opnform.test).
|
||||
|
||||
## One-Click Deployment
|
||||
|
||||
[](https://repocloud.io/details/?app_id=294)
|
||||
|
||||
## Tech Stack
|
||||
|
||||
OpnForm is a standard web application built with:
|
||||
|
||||
- [Laravel](https://laravel.com/) PHP framework
|
||||
- [NuxtJs](https://nuxt.com/) Front-end SSR framework
|
||||
- [Vue.js 3](https://vuejs.org/) Front-end framework
|
||||
- [TailwindCSS](https://tailwindcss.com/)
|
||||
|
||||
## Contribute
|
||||
|
||||
You're more than welcome to contribute to this project. We don't have guidelines on this yet, but we will soon. In the meantime, feel free to ask [any question here](https://github.com/JhumanJ/OpnForm/discussions).
|
||||
- [Product Helpdesk](https://help.opnform.com)
|
||||
- [Technical Documentation](https://docs.opnform.com)
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
|
|
@ -21,21 +21,6 @@
|
|||
</div>
|
||||
<div class="flex justify-center mt-5 md:mt-0">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-x-4 gap-y-2">
|
||||
<template v-if="!useFeatureFlag('self_hosted')">
|
||||
<router-link
|
||||
:to="{ name: 'privacy-policy' }"
|
||||
class="text-gray-600 dark:text-gray-400 transition-colors duration-300 hover:text-nt-blue"
|
||||
>
|
||||
Privacy Policy
|
||||
</router-link>
|
||||
|
||||
<router-link
|
||||
:to="{ name: 'terms-conditions' }"
|
||||
class="text-gray-600 dark:text-gray-400 transition-colors duration-300 hover:text-nt-blue"
|
||||
>
|
||||
Terms & Conditions
|
||||
</router-link>
|
||||
</template>
|
||||
<a
|
||||
:href="opnformConfig.links.feature_requests"
|
||||
target="_blank"
|
||||
|
|
@ -57,6 +42,28 @@
|
|||
>
|
||||
Discord
|
||||
</a>
|
||||
<a
|
||||
:href="opnformConfig.links.tech_docs"
|
||||
target="_blank"
|
||||
class="text-gray-600 dark:text-gray-400 transition-colors duration-300 hover:text-nt-blue"
|
||||
>
|
||||
Technical Docs
|
||||
</a>
|
||||
<template v-if="!useFeatureFlag('self_hosted')">
|
||||
<router-link
|
||||
:to="{ name: 'privacy-policy' }"
|
||||
class="text-gray-600 dark:text-gray-400 transition-colors duration-300 hover:text-nt-blue"
|
||||
>
|
||||
Privacy Policy
|
||||
</router-link>
|
||||
|
||||
<router-link
|
||||
:to="{ name: 'terms-conditions' }"
|
||||
class="text-gray-600 dark:text-gray-400 transition-colors duration-300 hover:text-nt-blue"
|
||||
>
|
||||
Terms & Conditions
|
||||
</router-link>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -16,5 +16,6 @@ export default {
|
|||
feature_requests: "https://feedback.opnform.com/",
|
||||
changelog_url: "https://feedback.opnform.com/changelog",
|
||||
roadmap: "https://feedback.opnform.com/roadmap",
|
||||
tech_docs: "https://docs.opnform.com",
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 300 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: "List Forms"
|
||||
openapi: "GET /external/zapier/forms"
|
||||
---
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: "New Submission Trigger"
|
||||
openapi: "POST /external/zapier/webhook"
|
||||
---
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: "Sample Submission Polling"
|
||||
openapi: "GET /external/zapier/submissions/recent"
|
||||
---
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: "Unsubscribe Webhook"
|
||||
openapi: "DELETE /external/zapier/webhook"
|
||||
---
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: "Validate API Key"
|
||||
openapi: "GET /external/zapier/validate"
|
||||
---
|
||||
|
After Width: | Height: | Size: 222 KiB |
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
title: "Introduction"
|
||||
description: "API Documentation for OpnForm"
|
||||
---
|
||||
|
||||
Welcome to the OpnForm API documentation. This guide provides information on how to interact with the OpnForm API to automate your workflows and integrate OpnForm with your applications.
|
||||
|
||||
## Authentication
|
||||
|
||||
To authenticate with the OpnForm API, you need an API key. Here's how to create and use an API key.
|
||||
|
||||
### Creating an API Key
|
||||
|
||||
<Frame>
|
||||
<img
|
||||
src="/api-reference/images/create-token.png"
|
||||
alt="Creating an API Key in OpnForm"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
1. Log in to your OpnForm account.
|
||||
2. Navigate to the Access Tokens page at https://opnform.com/settings/access-tokens.
|
||||
3. Click on the "Create new token" button.
|
||||
4. Give your token a name (e.g., "My API Integration").
|
||||
5. Click "Create" to generate your API key. 6. Copy the generated API key immediately, as it won't be displayed again for security reasons.
|
||||
|
||||
### Using the API Key
|
||||
|
||||
To use the API key, you need to include it in the header of every request you make to the API as a Bearer token. Here's how to do it:
|
||||
|
||||
1. Take your API key that you generated earlier.
|
||||
2. Add it to the `Authorization` header of your HTTP request.
|
||||
3. Prefix the key with the word "Bearer" followed by a space.
|
||||
|
||||
```
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
```
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
{
|
||||
"openapi": "3.0.1",
|
||||
"info": {
|
||||
"title": "OpnForm API",
|
||||
"description": "API for interacting with OpnForm, primarily used for Zapier integration",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "https://api.opnform.com"
|
||||
}
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": []
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/external/zapier/validate": {
|
||||
"get": {
|
||||
"summary": "Validate API Key",
|
||||
"description": "This endpoint is used by Zapier to test the validity of the API key.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "API key is valid"
|
||||
},
|
||||
"401": {
|
||||
"description": "Invalid API key"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/external/zapier/forms": {
|
||||
"get": {
|
||||
"summary": "List Forms",
|
||||
"description": "Retrieve a list of forms available in a specific workspace.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "workspace_id",
|
||||
"in": "query",
|
||||
"description": "The ID of the workspace for which to list forms",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Form"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/external/zapier/webhook": {
|
||||
"post": {
|
||||
"summary": "New Submission Trigger",
|
||||
"description": "This endpoint is used to set up a webhook for new form submissions.",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"hookUrl": {
|
||||
"type": "string",
|
||||
"description": "The URL provided by Zapier to send the submission data"
|
||||
},
|
||||
"form_id": {
|
||||
"type": "string",
|
||||
"description": "The ID of the form for which to trigger the webhook"
|
||||
}
|
||||
},
|
||||
"required": ["hookUrl", "form_id"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Webhook successfully set up"
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"summary": "Unsubscribe Webhook",
|
||||
"description": "This endpoint is used to unsubscribe from the webhook.",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"hookUrl": {
|
||||
"type": "string",
|
||||
"description": "The URL provided by Zapier to stop sending the submission data"
|
||||
},
|
||||
"form_id": {
|
||||
"type": "string",
|
||||
"description": "The ID of the form for which to unsubscribe the webhook"
|
||||
}
|
||||
},
|
||||
"required": ["hookUrl", "form_id"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Webhook successfully unsubscribed"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/external/zapier/submissions/recent": {
|
||||
"get": {
|
||||
"summary": "Sample Submission Polling",
|
||||
"description": "Retrieves the most recent submissions for a specified form.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "form_id",
|
||||
"in": "query",
|
||||
"description": "The ID of the form to retrieve submissions for",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Submission"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Form": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Submission": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"submission_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"form_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"submitted_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securitySchemes": {
|
||||
"bearerAuth": {
|
||||
"type": "http",
|
||||
"scheme": "bearer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
title: AWS S3 Configuration
|
||||
description: OpnForm & File uploads
|
||||
---
|
||||
|
||||
OpnForm uses [Laravel's filesystem](https://laravel.com/docs/master/filesystem), which provides a powerful abstraction layer for various file storage systems. While AWS S3 is a popular choice, OpnForm supports both local storage and S3-compatible services.
|
||||
|
||||
1. Create an S3 bucket in your AWS account (or use an equivalent service).
|
||||
|
||||
2. Create an IAM user with access to this bucket. Ensure the user has the necessary permissions to read from and write to the bucket.
|
||||
|
||||
3. Configure CORS for the S3 bucket permissions, by adding the following under "Cross-origin resource sharing (CORS)":
|
||||
```json
|
||||
[
|
||||
{
|
||||
"AllowedHeaders": ["*"],
|
||||
"AllowedMethods": ["PUT", "POST", "GET", "DELETE"],
|
||||
"AllowedOrigins": ["*"],
|
||||
"ExposeHeaders": []
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
4. Set the following environment variables in your OpnForm installation (`api/.env`):
|
||||
- `AWS_ACCESS_KEY_ID`: Your IAM user's access key ID
|
||||
- `AWS_SECRET_ACCESS_KEY`: Your IAM user's secret access key
|
||||
- `AWS_DEFAULT_REGION`: The AWS region where your S3 bucket is located
|
||||
- `AWS_BUCKET`: The name of your S3 bucket
|
||||
|
||||
These settings will enable OpnForm to use your S3 bucket for file storage.
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Using your own domain
|
||||
description: Setting up a custom domain for OpnForm
|
||||
---
|
||||
|
||||
This page explains how to configure a custom domain for your OpnForm instance.
|
||||
## Custom Domain Setup
|
||||
|
||||
To use a custom domain (or subdomain)with OpnForm:
|
||||
|
||||
1. Purchase a domain (if needed)
|
||||
2. Configure DNS records to point to your OpnForm instance
|
||||
3. Update OpnForm configuration:
|
||||
- Set `APP_URL` in `.env`
|
||||
- Set `NUXT_PUBLIC_APP_URL` and `NUXT_PUBLIC_API_BASE` in `client/.env`
|
||||
4. Secure with SSL certificate
|
||||
|
||||
import CloudVersion from "/snippets/cloud-version.mdx";
|
||||
|
||||
<CloudVersion/>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
title: Email Setup
|
||||
description: OpnForm & Emails
|
||||
---
|
||||
|
||||
This page explains how to configure email notifications in OpnForm.
|
||||
|
||||
By default, with a new Docker deployment, the email driver used is `log`, which simply logs the emails instead of sending them. To enable actual email sending, you need to set up a proper email configuration.
|
||||
|
||||
OpnForm uses Laravel's mail system. For more detailed information, you can refer to the [Laravel Mail documentation](https://laravel.com/docs/master/mail).
|
||||
|
||||
## Supported Mail Drivers
|
||||
|
||||
Laravel supports various mail drivers, including SMTP, Mailgun, Postmark, Amazon SES, and more. In this guide, we'll focus on setting up SMTP, which is widely used.
|
||||
|
||||
## Configuring SMTP Settings
|
||||
|
||||
To configure SMTP, you need to set the following environment variables in your `.env` file:
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `MAIL_MAILER` | Set this to `smtp` to use the SMTP driver. |
|
||||
| `MAIL_HOST` | The address of your SMTP server. |
|
||||
| `MAIL_PORT` | The port used by your SMTP server (common ports are 25, 465, and 587). |
|
||||
| `MAIL_USERNAME` | The username for your SMTP account. |
|
||||
| `MAIL_PASSWORD` | The password for your SMTP account. |
|
||||
| `MAIL_ENCRYPTION` | The encryption method used by your SMTP server (typically `tls` or `ssl`). |
|
||||
| `MAIL_FROM_ADDRESS` | The email address that emails should be sent from. |
|
||||
| `MAIL_FROM_NAME` | The name that should appear as the sender of the emails. |
|
||||
|
||||
import CloudVersion from "/snippets/cloud-version.mdx";
|
||||
|
||||
<CloudVersion/>
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
title: Environment Variables Configuration
|
||||
description: Detailed guide on configuring environment variables for OpnForm
|
||||
---
|
||||
|
||||
OpnForm uses two `.env` files for configuration: one for the Laravel backend located in the `api` directory, and one for the Nuxt front-end located in the `client` directory.
|
||||
|
||||
## Backend Environment Variables
|
||||
|
||||
The following environment variables are used to [configure the Laravel](https://laravel.com/docs/11.x/configuration) application (OpnForm's API).
|
||||
|
||||
### Dedicated guides
|
||||
There are dedicated configuration pages available for more detailed setup instructions on specific topics:
|
||||
- [File Storage (S3)](../configuration/aws-s3)
|
||||
- [Email Configuration (SMTP)](../configuration/email-setup)
|
||||
- [Custom Domain](../configuration/custom-domain)
|
||||
|
||||
|
||||
### Other Environment Variables
|
||||
|
||||
### Configuration Environment Variables
|
||||
|
||||
| Variable Name | Description |
|
||||
|------------------------------|--------------------------------------------------|
|
||||
| `JWT_TTL` | Time to live for JSON Web Tokens (JWT). |
|
||||
| `JWT_SECRET` | Secret key used to sign JWTs. |
|
||||
| `H_CAPTCHA_SITE_KEY` | Site key for hCaptcha integration. |
|
||||
| `H_CAPTCHA_SECRET_KEY` | Secret key for hCaptcha integration. |
|
||||
| `OPEN_AI_API_KEY` | API key for accessing OpenAI services. |
|
||||
| `UNSPLASH_ACCESS_KEY` | Access key for Unsplash API. |
|
||||
| `UNSPLASH_SECRET_KEY` | Secret key for Unsplash API. |
|
||||
| `GOOGLE_CLIENT_ID` | Client ID for Google OAuth. |
|
||||
| `GOOGLE_CLIENT_SECRET` | Client secret for Google OAuth. |
|
||||
| `GOOGLE_REDIRECT_URL` | Redirect URL for Google OAuth. |
|
||||
| `GOOGLE_AUTH_REDIRECT_URL` | Authentication redirect URL for Google OAuth. |
|
||||
| `GOOGLE_FONTS_API_KEY` | API key for accessing Google Fonts. |
|
||||
| `FRONT_URL` | Public facing URL of the front-end. |
|
||||
| `FRONT_API_SECRET` | Shared secret with the front-end. |
|
||||
|
||||
### User Options Environment Variables
|
||||
|
||||
| Variable Name | Description |
|
||||
|------------------------------|--------------------------------------------------|
|
||||
| `ADMIN_EMAILS` | Comma-separated list of admin email addresses. |
|
||||
| `TEMPLATE_EDITOR_EMAILS` | Comma-separated list of template editor emails. |
|
||||
| `EXTRA_PRO_USERS_EMAILS` | Comma-separated list of extra pro user emails. |
|
||||
| `MODERATOR_EMAILS` | Comma-separated list of moderator email addresses. |
|
||||
|
||||
|
||||
## Front-end Environment Variables
|
||||
|
||||
### Front-end Environment Variables
|
||||
|
||||
| Variable Name | Description |
|
||||
|------------------------------|--------------------------------------------------|
|
||||
| `NUXT_PUBLIC_APP_URL` | Public facing URL of the Nuxt application. |
|
||||
| `NUXT_PUBLIC_API_BASE` | Base URL for the Laravel API. |
|
||||
| `NUXT_PUBLIC_H_CAPTCHA_SITE_KEY` | Site key for hCaptcha integration on the front-end. |
|
||||
| `NUXT_API_SECRET` | Shared secret key between Nuxt and Laravel backend. |
|
||||
|
||||
|
||||
import CloudVersion from "/snippets/cloud-version.mdx";
|
||||
|
||||
<CloudVersion/>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# Bounties
|
||||
|
||||
This page will explain the bounty system for OpnForm contributions.
|
||||
|
||||
Topics include:
|
||||
|
||||
- How the bounty system works
|
||||
- Current open bounties
|
||||
- How to claim a bounty
|
||||
- Payout process
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: "Getting Started with Contributing"
|
||||
description: "Learn how to contribute to OpnForm"
|
||||
---
|
||||
|
||||
Welcome to the OpnForm contributing guide! Here are some helpful links to get you started:
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Setting up the development environment" icon="gear" href="../configuration/environment-variables">
|
||||
Learn how to configure the environment variables for OpnForm.
|
||||
</Card>
|
||||
<Card title="Adding a new form block" icon="puzzle-piece" href="new-form-block">
|
||||
Follow the steps to add a new form block to your project.
|
||||
</Card>
|
||||
<Card title="Integrating new services" icon="plug" href="new-integration">
|
||||
Discover how to integrate new services with OpnForm.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
We sometimes offer bounties for certain issues. Check out our [bounties page](https://console.algora.io/org/OpnForm) for more information.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "Creating a New Form Block"
|
||||
description: "Learn how to create a new form block for OpnForm"
|
||||
---
|
||||
|
||||
<Warning>Whoops not ready yet! This page is still to be written.</Warning>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "Adding a New Integration"
|
||||
description: "Learn how to add a new integration to OpnForm"
|
||||
---
|
||||
|
||||
<Warning>Whoops not ready yet! This page is still to be written.</Warning>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
title: "Cloud vs Self-Hosting"
|
||||
description: "Understand the differences between cloud and self-hosting options for OpnForm"
|
||||
---
|
||||
|
||||
When deciding between using OpnForm's cloud service or self-hosting, it's important to understand the key differences and benefits of each option. Below is a comparison to help you make an informed decision:
|
||||
|
||||
| | Self-Hosted | OpnForm Cloud |
|
||||
| ------------------------------ | ----------------------------------- | ---------------------------------- |
|
||||
| High availability servers | \~$50+/month | ✅ |
|
||||
| Load balancer | \~$15+/month | ✅ |
|
||||
| Managed database | \~$45-70+/month | ✅ |
|
||||
| SMTP server | \~$15+/month | ✅ |
|
||||
| Support | Discord | Live Chat |
|
||||
| Setup time | Manual | ✅ Up and running in minutes |
|
||||
| Upgrades | Manual | ✅ Automatic |
|
||||
| Multi-zone availability | Manual | ✅ |
|
||||
| Backups | Manual | ✅ Automatic |
|
||||
| Monitoring | Manual | ✅ |
|
||||
| Custom code and forks | ✅ | ❌ |
|
||||
| SSL certificate | Manual | ✅ |
|
||||
| Where your money goes | 3rd-party services | Improving OpnForm |
|
||||
|
||||
### When Should You Self-Host?
|
||||
|
||||
There are specific scenarios where self-hosting OpnForm might be the better choice:
|
||||
|
||||
- **Regulatory Compliance**: If you need an air-gapped environment for regulatory reasons (e.g., HIPAA compliance).
|
||||
- **Custom Builds**: If you want to run a custom build or fork of OpnForm with your own customizations.
|
||||
- **Custom Integrations**: If you need to use community or custom integrations that are not supported in the cloud version.
|
||||
|
||||
For most users, the managed OpnForm Cloud service will be the better option due to its ease of use, automatic updates, and comprehensive support.
|
||||
|
||||
*This comparison is inspired by the [Metabase Cloud vs Self-Hosting page](https://www.metabase.com/docs/latest/cloud/cloud-vs-self-hosting).*
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
---
|
||||
title: "Docker"
|
||||
description: "OpnForm can be easily set up using Docker. We provide pre-built images on Docker Hub, which is the recommended method for most users."
|
||||
---
|
||||
|
||||
import CloudVersion from "/snippets/cloud-version.mdx";
|
||||
|
||||
<CloudVersion/>
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker
|
||||
- Docker Compose
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/JhumanJ/OpnForm.git
|
||||
cd OpnForm
|
||||
```
|
||||
|
||||
2. Set up environment files:
|
||||
|
||||
```bash
|
||||
./scripts/setup-env.sh --docker
|
||||
```
|
||||
|
||||
3. (Optional) Customize the environment variables:
|
||||
|
||||
You can modify two environment files to customize your OpnForm installation:
|
||||
- The `.env` file in the `api` directory for backend configuration
|
||||
- The `.env` file in the `client` directory for frontend configuration
|
||||
|
||||
For more information on available environment variables, please refer to our [Environment Variables](/configuration/environment-variables) page.
|
||||
|
||||
4. Start the application:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
5. Access OpnForm at http://localhost
|
||||
|
||||
|
||||
## Docker Images
|
||||
|
||||
OpnForm provides pre-built Docker images for easy deployment. You can find our official Docker images on Docker Hub:
|
||||
|
||||
- [OpnForm API Image](https://hub.docker.com/r/jhumanj/opnform-api)
|
||||
- [OpnForm Client Image](https://hub.docker.com/r/jhumanj/opnform-client)
|
||||
|
||||
We recommend using these official images for your OpnForm deployment.
|
||||
|
||||
|
||||
## Building Your Own Docker Images
|
||||
|
||||
If you prefer to build your own Docker images, you can do so using the provided Dockerfiles in the repository:
|
||||
|
||||
1. Build the API image:
|
||||
```bash
|
||||
docker build -t opnform-api:local -f docker/Dockerfile.api .
|
||||
```
|
||||
|
||||
2. Build the UI image:
|
||||
```bash
|
||||
docker build -t opnform-ui:local -f docker/Dockerfile.client .
|
||||
```
|
||||
|
||||
### Overriding Docker Compose Configuration
|
||||
|
||||
You can override the default Docker Compose configuration by creating a `docker-compose.override.yml` file. This allows you to customize various aspects of the deployment without modifying the main `docker-compose.yml` file.
|
||||
|
||||
Example `docker-compose.override.yml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
api:
|
||||
image: opnform-api:local
|
||||
ui:
|
||||
image: opnform-ui:local
|
||||
api-worker:
|
||||
image: opnform-api:local
|
||||
```
|
||||
|
||||
|
||||
### Clearing all resources
|
||||
|
||||
To completely remove all Docker containers, networks, and volumes created by docker-compose and also remove all images used by these services, you can use the following command:
|
||||
|
||||
```
|
||||
docker-compose down -v --rmi all
|
||||
```
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
title: "Local Deployment"
|
||||
description: "Set up OpnForm locally for development"
|
||||
---
|
||||
|
||||
import CloudVersion from "/snippets/cloud-version.mdx";
|
||||
|
||||
<CloudVersion/>
|
||||
|
||||
## Requirements
|
||||
|
||||
Before proceeding with the local deployment, ensure you have the following prerequisites installed on your system:
|
||||
|
||||
- **PHP**: Version 8.0 or higher
|
||||
- **Composer**: The PHP dependency manager
|
||||
- **Node.js**: Version 14 or higher
|
||||
- **NPM** or **Yarn**: Package managers for Node.js
|
||||
- **MySQL**, or **PostgreSQL**: A supported database system
|
||||
|
||||
Make sure these components are properly installed and configured on your local machine before proceeding with the deployment steps.
|
||||
|
||||
## Local setup
|
||||
|
||||
1. Install Laravel Herd -Download and install Laravel Herd from the official website: https://herd.laravel.com/
|
||||
|
||||
2. Clone the repository and install dependencies:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:JhumanJ/OpnForm.git && cd OpnForm
|
||||
cd api && composer install
|
||||
cd ../client && npm install
|
||||
```
|
||||
|
||||
3. Compile assets and run dev server:
|
||||
|
||||
```bash
|
||||
cd client && npm run dev # or build
|
||||
```
|
||||
|
||||
4. Set up environment files:
|
||||
|
||||
```bash
|
||||
./scripts/setup-env.sh
|
||||
```
|
||||
This script will create the necessary `.env` files for both the API and client.
|
||||
|
||||
5. Run the migrations:
|
||||
|
||||
```bash
|
||||
cd api
|
||||
php artisan migrate
|
||||
```
|
||||
|
||||
6. Set up Herd:
|
||||
For detailed instructions on setting up Herd, refer to the [Herd documentation](https://herd.laravel.com/docs).
|
||||
- Open the Herd application
|
||||
- Add your OpnForm's `api` directory to Herd
|
||||
- Herd will automatically configure a local domain for your project
|
||||
|
||||
This will start the Nuxt.js development server, typically on `http://localhost:3000`.
|
||||
|
||||
8. Access your local OpnForm installation:
|
||||
- The API will be available at the domain provided by Herd (e.g., `http://opnform.test`)
|
||||
- The frontend will be accessible at `http://localhost:3000`
|
||||
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -0,0 +1,49 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="white"/>
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="url(#paint0_radial_101_2703)"/>
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="black" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="url(#paint1_linear_101_2703)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M8.68359 10.4755C9.94543 13.63 9.56145 17.5723 7.9354 21.1112C4.89702 21.0957 2.27411 19.4306 1.01347 16.279C-0.248375 13.1245 0.135612 9.18218 1.76165 5.64328C4.80004 5.65883 7.42295 7.32386 8.68359 10.4755Z" stroke="url(#paint2_linear_101_2703)" stroke-opacity="0.05" stroke-width="0.056338"/>
|
||||
<path d="M7.31038 21.2574C11.3543 20.2215 14.8836 17.3754 16.6285 13.2361C18.3735 9.09671 17.9448 4.58749 15.8598 0.976291C11.8159 2.01214 8.2866 4.85826 6.54167 8.99762C4.79674 13.137 5.2254 17.6462 7.31038 21.2574Z" fill="white"/>
|
||||
<path d="M7.31038 21.2574C11.3543 20.2215 14.8836 17.3754 16.6285 13.2361C18.3735 9.09671 17.9448 4.58749 15.8598 0.976291C11.8159 2.01214 8.2866 4.85826 6.54167 8.99762C4.79674 13.137 5.2254 17.6462 7.31038 21.2574Z" fill="url(#paint3_radial_101_2703)"/>
|
||||
<path d="M16.6026 13.2251C14.8642 17.349 11.3512 20.1866 7.32411 21.2248C5.25257 17.624 4.82926 13.1324 6.56764 9.00855C8.30603 4.88472 11.819 2.04706 15.8461 1.00889C17.9176 4.60967 18.3409 9.10131 16.6026 13.2251Z" stroke="url(#paint4_linear_101_2703)" stroke-opacity="0.05" stroke-width="0.056338"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="white"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="url(#paint5_radial_101_2703)"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="black" fill-opacity="0.2" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="url(#paint6_linear_101_2703)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M16.5682 22.7874C13.2176 23.9184 9.81361 23.2124 7.2672 21.1975C8.49194 17.9068 11.0444 15.189 14.3959 14.0577C17.7465 12.9266 21.1504 13.6326 23.6968 15.6476C22.4721 18.9383 19.9196 21.656 16.5682 22.7874Z" stroke="url(#paint7_linear_101_2703)" stroke-opacity="0.05" stroke-width="0.056338"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_101_2703" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(-3.00503 15.023) rotate(-10.029) scale(17.9572 17.784)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint1_linear_101_2703" x1="7.39036" y1="4.81308" x2="1.62975" y2="18.6894" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_101_2703" x1="7.94816" y1="8.01563" x2="1.7612" y2="18.746" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint3_radial_101_2703" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(8.11404 20.8822) rotate(-75.7542) scale(21.6246 23.7772)">
|
||||
<stop stop-color="#00BBBB"/>
|
||||
<stop offset="0.712616" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint4_linear_101_2703" x1="7.60205" y1="5.8709" x2="15.5561" y2="16.3719" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint5_radial_101_2703" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(7.84537 21.5181) rotate(-20.3525) scale(18.5603 17.32)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint6_linear_101_2703" x1="16.8078" y1="13.0071" x2="10.0409" y2="22.9937" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00B1BC"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_101_2703" x1="16.8078" y1="13.0071" x2="14.1687" y2="23.841" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 157 KiB |
|
|
@ -0,0 +1,161 @@
|
|||
<svg width="700" height="320" viewBox="0 0 700 320" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2862_30)">
|
||||
<rect width="700" height="320" rx="16" fill="url(#paint0_linear_2862_30)"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="white"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="url(#paint1_radial_2862_30)"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="black" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="url(#paint2_linear_2862_30)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M311.72 247.034C283.108 246.887 258.409 231.208 246.538 201.531C234.656 171.825 238.271 134.702 253.583 101.377C282.195 101.524 306.894 117.203 318.765 146.88C330.647 176.586 327.031 213.709 311.72 247.034Z" stroke="url(#paint3_linear_2862_30)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<path d="M305.839 247.174C343.92 237.419 377.154 210.619 393.585 171.64C410.017 132.661 405.98 90.1988 386.347 56.1934C348.266 65.9477 315.032 92.7486 298.601 131.728C282.169 170.706 286.206 213.168 305.839 247.174Z" fill="white"/>
|
||||
<path d="M305.839 247.174C343.92 237.419 377.154 210.619 393.585 171.64C410.017 132.661 405.98 90.1988 386.347 56.1934C348.266 65.9477 315.032 92.7486 298.601 131.728C282.169 170.706 286.206 213.168 305.839 247.174Z" fill="url(#paint4_radial_2862_30)"/>
|
||||
<path d="M393.341 171.537C376.971 210.369 343.89 237.091 305.969 246.867C286.462 212.959 282.476 170.663 298.845 131.831C315.215 92.9978 348.295 66.2765 386.217 56.5004C405.724 90.4077 409.71 132.704 393.341 171.537Z" stroke="url(#paint5_linear_2862_30)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<path d="M305.686 246.995C329.749 266.114 361.965 272.832 393.67 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.045 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="white"/>
|
||||
<path d="M305.686 246.995C329.749 266.114 361.965 272.832 393.67 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.045 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="url(#paint6_radial_2862_30)"/>
|
||||
<path d="M305.686 246.995C329.749 266.114 361.965 272.832 393.67 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.045 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="black" fill-opacity="0.2" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M305.686 246.995C329.749 266.114 361.965 272.832 393.67 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.045 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="url(#paint7_linear_2862_30)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M393.586 261.878C362.034 272.529 329.98 265.88 306.002 246.907C317.534 215.919 341.57 190.327 373.13 179.673C404.681 169.023 436.735 175.671 460.714 194.644C449.181 225.632 425.145 251.224 393.586 261.878Z" stroke="url(#paint8_linear_2862_30)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<g opacity="0.8" filter="url(#filter0_f_2862_30)">
|
||||
<circle cx="660" cy="-60" r="160" fill="#18E244" fill-opacity="0.4"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter1_f_2862_30)">
|
||||
<circle cx="20" cy="213" r="160" fill="#18CAE2" fill-opacity="0.33"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter2_f_2862_30)">
|
||||
<circle cx="660" cy="480" r="160" fill="#18E2B2" fill-opacity="0.52"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter3_f_2862_30)">
|
||||
<circle cx="20" cy="413" r="160" fill="#4018E2" fill-opacity="0.22"/>
|
||||
</g>
|
||||
<path opacity="0.2" d="M0 50H700" stroke="url(#paint9_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.1" d="M0 82H700" stroke="url(#paint10_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.2" d="M239 0L239 320" stroke="url(#paint11_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.1" d="M271 0L271 320" stroke="url(#paint12_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.2" d="M461 0L461 320" stroke="url(#paint13_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.1" d="M429 0L429 320" stroke="url(#paint14_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.2" d="M0 271H700" stroke="url(#paint15_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.1" d="M0 239H700" stroke="url(#paint16_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 160H700" stroke="url(#paint17_linear_2862_30)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.2">
|
||||
<path d="M511 -1L189 321" stroke="url(#paint18_linear_2862_30)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.2">
|
||||
<path d="M511 321L189 -1" stroke="url(#paint19_linear_2862_30)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<circle cx="350" cy="160" r="111" stroke="white"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<circle cx="350" cy="160" r="79" stroke="white"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_2862_30" x="260" y="-460" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_30"/>
|
||||
</filter>
|
||||
<filter id="filter1_f_2862_30" x="-380" y="-187" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_30"/>
|
||||
</filter>
|
||||
<filter id="filter2_f_2862_30" x="260" y="80" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_30"/>
|
||||
</filter>
|
||||
<filter id="filter3_f_2862_30" x="-380" y="13" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_30"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_2862_30" x1="1.04308e-05" y1="320" x2="710.784" y2="26.0793" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299" stop-opacity="0.09"/>
|
||||
<stop offset="0.729167" stop-color="#0D9373" stop-opacity="0.08"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint1_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(208.697 189.703) rotate(-10.029) scale(169.097 167.466)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint2_linear_2862_30" x1="306.587" y1="93.5598" x2="252.341" y2="224.228" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_2862_30" x1="311.84" y1="123.717" x2="253.579" y2="224.761" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint4_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(313.407 243.64) rotate(-75.7542) scale(203.632 223.902)">
|
||||
<stop stop-color="#00BBBB"/>
|
||||
<stop offset="0.712616" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint5_linear_2862_30" x1="308.586" y1="102.284" x2="383.487" y2="201.169" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint6_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(311.446 249.925) rotate(-20.3524) scale(174.776 163.096)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint7_linear_2862_30" x1="395.842" y1="169.781" x2="332.121" y2="263.82" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00B1BC"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_2862_30" x1="395.842" y1="169.781" x2="370.99" y2="271.799" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint9_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(350 50) scale(398.125 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint10_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(350 82) scale(398.125 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint11_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(239 160) rotate(90) scale(182 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint12_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(271 160) rotate(90) scale(182 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint13_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(461 160) rotate(90) scale(182 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint14_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(429 160) rotate(90) scale(182 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint15_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(350 271) scale(398.125 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint16_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(350 239) scale(398.125 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint17_linear_2862_30" x1="0" y1="160" x2="700" y2="160" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.1"/>
|
||||
<stop offset="0.5" stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint18_linear_2862_30" x1="511" y1="-1" x2="189" y2="321" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.1"/>
|
||||
<stop offset="0.5" stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint19_linear_2862_30" x1="511" y1="321" x2="189" y2="-0.999997" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.1"/>
|
||||
<stop offset="0.5" stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_2862_30">
|
||||
<rect width="700" height="320" rx="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -0,0 +1,155 @@
|
|||
<svg width="700" height="320" viewBox="0 0 700 320" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2862_278)">
|
||||
<rect width="700" height="320" rx="16" fill="url(#paint0_linear_2862_278)"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="white"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="url(#paint1_radial_2862_278)"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="black" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="url(#paint2_linear_2862_278)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M311.72 247.034C283.108 246.887 258.409 231.208 246.538 201.531C234.656 171.825 238.271 134.702 253.583 101.377C282.195 101.524 306.894 117.203 318.765 146.88C330.647 176.586 327.031 213.709 311.72 247.034Z" stroke="url(#paint3_linear_2862_278)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<path d="M305.839 247.174C343.92 237.419 377.154 210.619 393.585 171.64C410.017 132.661 405.98 90.1988 386.347 56.1934C348.266 65.9477 315.032 92.7486 298.601 131.728C282.169 170.706 286.206 213.168 305.839 247.174Z" fill="white"/>
|
||||
<path d="M305.839 247.174C343.92 237.419 377.154 210.619 393.585 171.64C410.017 132.661 405.98 90.1988 386.347 56.1934C348.266 65.9477 315.032 92.7486 298.601 131.728C282.169 170.706 286.206 213.168 305.839 247.174Z" fill="url(#paint4_radial_2862_278)"/>
|
||||
<path d="M393.341 171.537C376.971 210.369 343.89 237.091 305.969 246.867C286.462 212.959 282.476 170.663 298.845 131.831C315.215 92.9978 348.295 66.2765 386.217 56.5004C405.724 90.4077 409.71 132.704 393.341 171.537Z" stroke="url(#paint5_linear_2862_278)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<path d="M305.686 246.995C329.75 266.114 361.965 272.832 393.671 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.046 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="white"/>
|
||||
<path d="M305.686 246.995C329.75 266.114 361.965 272.832 393.671 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.046 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="url(#paint6_radial_2862_278)"/>
|
||||
<path d="M305.686 246.995C329.75 266.114 361.965 272.832 393.671 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.046 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="black" fill-opacity="0.2" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M305.686 246.995C329.75 266.114 361.965 272.832 393.671 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.046 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="url(#paint7_linear_2862_278)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M393.586 261.878C362.035 272.529 329.981 265.88 306.002 246.907C317.535 215.919 341.571 190.327 373.13 179.673C404.682 169.023 436.736 175.671 460.715 194.644C449.182 225.632 425.146 251.224 393.586 261.878Z" stroke="url(#paint8_linear_2862_278)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<g opacity="0.8" filter="url(#filter0_f_2862_278)">
|
||||
<circle cx="660" cy="-60" r="160" fill="#18E299" fill-opacity="0.4"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter1_f_2862_278)">
|
||||
<circle cx="20" cy="213" r="160" fill="#18E299" fill-opacity="0.33"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter2_f_2862_278)">
|
||||
<circle cx="660" cy="480" r="160" fill="#18E299" fill-opacity="0.52"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter3_f_2862_278)">
|
||||
<circle cx="20" cy="413" r="160" fill="#18E299" fill-opacity="0.22"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 50H700" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 82H700" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M239 0L239 320" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M271 0L271 320" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M461 0L461 320" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M350 0L350 320" stroke="url(#paint9_linear_2862_278)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M429 0L429 320" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 271H700" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 239H700" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 160H700" stroke="url(#paint10_linear_2862_278)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M511 -1L189 321" stroke="url(#paint11_linear_2862_278)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M511 321L189 -1" stroke="url(#paint12_linear_2862_278)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.05">
|
||||
<circle cx="350" cy="160" r="111" stroke="black"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.05">
|
||||
<circle cx="350" cy="160" r="79" stroke="black"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_2862_278" x="260" y="-460" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_278"/>
|
||||
</filter>
|
||||
<filter id="filter1_f_2862_278" x="-380" y="-187" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_278"/>
|
||||
</filter>
|
||||
<filter id="filter2_f_2862_278" x="260" y="80" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_278"/>
|
||||
</filter>
|
||||
<filter id="filter3_f_2862_278" x="-380" y="13" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_278"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_2862_278" x1="1.04308e-05" y1="320" x2="710.784" y2="26.0793" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299" stop-opacity="0.09"/>
|
||||
<stop offset="0.729167" stop-color="#0D9373" stop-opacity="0.08"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint1_radial_2862_278" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(208.697 189.703) rotate(-10.029) scale(169.097 167.466)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint2_linear_2862_278" x1="306.587" y1="93.5598" x2="252.341" y2="224.228" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_2862_278" x1="311.84" y1="123.717" x2="253.579" y2="224.761" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint4_radial_2862_278" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(313.407 243.64) rotate(-75.7542) scale(203.632 223.902)">
|
||||
<stop stop-color="#00BBBB"/>
|
||||
<stop offset="0.712616" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint5_linear_2862_278" x1="308.586" y1="102.284" x2="383.487" y2="201.169" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint6_radial_2862_278" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(311.447 249.925) rotate(-20.3524) scale(174.776 163.096)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint7_linear_2862_278" x1="395.843" y1="169.781" x2="332.121" y2="263.82" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00B1BC"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_2862_278" x1="395.843" y1="169.781" x2="370.991" y2="271.799" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint9_linear_2862_278" x1="350" y1="0" x2="350" y2="320" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-opacity="0"/>
|
||||
<stop offset="0.0001" stop-opacity="0.3"/>
|
||||
<stop offset="0.333333"/>
|
||||
<stop offset="0.666667"/>
|
||||
<stop offset="1" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint10_linear_2862_278" x1="0" y1="160" x2="700" y2="160" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-opacity="0.1"/>
|
||||
<stop offset="0.5"/>
|
||||
<stop offset="1" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint11_linear_2862_278" x1="511" y1="-1" x2="189" y2="321" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-opacity="0.1"/>
|
||||
<stop offset="0.5"/>
|
||||
<stop offset="1" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint12_linear_2862_278" x1="511" y1="321" x2="189" y2="-0.999997" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-opacity="0.1"/>
|
||||
<stop offset="0.5"/>
|
||||
<stop offset="1" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_2862_278">
|
||||
<rect width="700" height="320" rx="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
title: "Introduction to OpnForm"
|
||||
description: "An open-source form builder"
|
||||
---
|
||||
|
||||
import CloudVersion from "/snippets/cloud-version.mdx";
|
||||
|
||||
OpnForm is an open-source form builder designed to empower developers and users alike. This technical documentation serves as your comprehensive guide to understanding, implementing, and contributing to OpnForm.
|
||||
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Cloud Version" icon="cloud" href="https://opnform.com/?utm_source=docs&utm_medium=introduction&utm_campaign=cloud_version">
|
||||
Managed service with high availability and security.
|
||||
</Card>
|
||||
<Card title="Deploy" icon="server" href="/deployment">
|
||||
Self-host OpnForm for full control and customization.
|
||||
</Card>
|
||||
<Card title="Contribute" icon="code-branch" href="/contributing">
|
||||
Join our open-source community and contribute.
|
||||
</Card>
|
||||
<Card title="API Reference" icon="book" href="/api-reference">
|
||||
Integrate OpnForm with our comprehensive API.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
For end-user documentation, feature explanations, and usage guides, please refer to our [Help Center](https://help.opnform.com).
|
||||
|
||||
## Features
|
||||
|
||||
- 🚀 No-code form builder with unlimited forms, fields & submissions
|
||||
- 📝 Various input types: Text, Date, URL, Phone, Email, Checkboxes, Select, Multi-Select, Number, Star-ratings, File uploads & more
|
||||
- 🌐 Embed anywhere (website, Notion page, etc.)
|
||||
- 📧 Email notifications for form owners & respondents
|
||||
- 🔒 Hidden fields and form passwords
|
||||
- 🔗 URL form pre-fill
|
||||
- 💬 Slack and Discord integrations
|
||||
- 🪝 Webhooks
|
||||
- 🧠 Form logic and AI-powered form generation
|
||||
- 🎨 Customizable colors, images, and custom code
|
||||
- 🛡️ Captcha form protection
|
||||
- 📅 Form closing date
|
||||
- 🔢 Limit on number of submissions
|
||||
- 📊 Form analytics
|
||||
- 📁 File uploads
|
||||
- 🆔 Unique submission ID
|
||||
- 📱 Single or multi-page forms
|
||||
- 🔍 Form templates for inspiration
|
||||
- 🔄 Editable submissions
|
||||
- 🌐 Custom domain
|
||||
- 🏷️ Remove OpnForm branding
|
||||
- 🔔 Form confirmation emails
|
||||
- ...[and more](https://opnform.com/pricing)!
|
||||
|
||||
<CloudVersion />
|
||||
|
|
@ -0,0 +1 @@
|
|||
<svg fill="none" height="120" viewBox="0 0 120 120" width="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="60" x2="60" y1="2" y2="118.352"><stop offset="0" stop-color="#2563eb"/><stop offset="1" stop-color="#60a5fa"/></linearGradient><path clip-rule="evenodd" d="m80.6502 118.352c22.9638-8.418 39.3498-30.4712 39.3498-56.352 0-33.1371-26.8629-60-60-60s-60 26.8629-60 60c0 25.8808 16.3862 47.934 39.3498 56.352l16.631-38.9411c-7.4746-1.9924-12.9808-8.8086-12.9808-16.9109 0-9.665 7.835-17.5 17.5-17.5s17.5 7.835 17.5 17.5c0 8.4269-5.9563 15.4627-13.8885 17.1269z" fill="url(#a)" fill-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 698 B |
|
|
@ -0,0 +1,122 @@
|
|||
{
|
||||
"$schema": "https://mintlify.com/schema.json",
|
||||
"name": "OpnForm Technical Docs",
|
||||
"logo": {
|
||||
"light": "/logo.svg",
|
||||
"dark": "/logo.svg"
|
||||
},
|
||||
"favicon": "/logo.svg",
|
||||
"colors": {
|
||||
"primary": "#3b82f6",
|
||||
"light": "#60a5fa",
|
||||
"dark": "#2563eb",
|
||||
"anchors": {
|
||||
"from": "#2563eb",
|
||||
"to": "#60a5fa"
|
||||
}
|
||||
},
|
||||
"topbarLinks": [
|
||||
{
|
||||
"name": "OpnForm",
|
||||
"url": "https://opnform.com?utm_source=docs&utm_medium=topbar&utm_campaign=technical_docs"
|
||||
},
|
||||
{
|
||||
"name": "GitHub",
|
||||
"url": "https://github.com/JhumanJ/OpnForm"
|
||||
}
|
||||
],
|
||||
"topbarCtaButton": {
|
||||
"name": "Dashboard",
|
||||
"url": "https://opnform.com"
|
||||
},
|
||||
"tabs": [
|
||||
{
|
||||
"name": "API Reference",
|
||||
"url": "api-reference"
|
||||
},
|
||||
{
|
||||
"name": "Contributing",
|
||||
"url": "contributing"
|
||||
}
|
||||
],
|
||||
"anchors": [
|
||||
{
|
||||
"name": "Product Documentation",
|
||||
"icon": "book-open-cover",
|
||||
"url": "https://help.opnform.com"
|
||||
},
|
||||
{
|
||||
"name": "Community",
|
||||
"icon": "discord",
|
||||
"url": "https://discord.gg/YTSjU2a9TS"
|
||||
},
|
||||
{
|
||||
"name": "Changelog",
|
||||
"icon": "sparkles",
|
||||
"url": "https://feedback.opnform.com/changelog"
|
||||
},
|
||||
{
|
||||
"name": "Roadmap",
|
||||
"icon": "road",
|
||||
"url": "https://feedback.opnform.com/roadmap"
|
||||
}
|
||||
],
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Get Started",
|
||||
"pages": [
|
||||
"introduction",
|
||||
"tech-stack"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Deployment",
|
||||
"pages": [
|
||||
"deployment/docker",
|
||||
"deployment/local-deployment",
|
||||
"deployment/cloud-vs-self-hosting"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Configuration",
|
||||
"pages": [
|
||||
"configuration/environment-variables",
|
||||
"configuration/aws-s3",
|
||||
"configuration/email-setup",
|
||||
"configuration/custom-domain"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "API Reference",
|
||||
"pages": [
|
||||
"api-reference/introduction"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Zapier Endpoints",
|
||||
"pages": [
|
||||
"api-reference/endpoint/validate-api-key",
|
||||
"api-reference/endpoint/list-forms",
|
||||
"api-reference/endpoint/new-submission-trigger",
|
||||
"api-reference/endpoint/unsubscribe-webhook",
|
||||
"api-reference/endpoint/sample-submission-polling"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Contributing",
|
||||
"pages": [
|
||||
"contributing/getting-started",
|
||||
"contributing/new-form-block",
|
||||
"contributing/new-integration"
|
||||
]
|
||||
}
|
||||
],
|
||||
"footerSocials": {
|
||||
"twitter": "https://twitter.com/opnform",
|
||||
"github": "https://github.com/JhumanJ/OpnForm"
|
||||
},
|
||||
"openapi": "/api-reference/openapi.json",
|
||||
"feedback": {
|
||||
"suggestEdit": true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<Note>
|
||||
The easiest way to get started with OpnForm is through our [official managed service in the Cloud](https://opnform.com/?utm_source=docs&utm_medium=introduction&utm_campaign=cloud_version). It takes just 1 minute to try out the builder for free, with high availability, backups, security, and maintenance all managed for you.
|
||||
</Note>
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
title: "Tech Stack"
|
||||
description: "Overview of OpnForm's technology stack"
|
||||
---
|
||||
|
||||
OpnForm is built using a modern and robust technology stack, ensuring high performance, scalability, and maintainability. Here's an overview of the main technologies used in the project:
|
||||
|
||||
## Backend
|
||||
|
||||
<Card title="PHP" icon="php" href="https://www.php.net/" horizontal>
|
||||
Version 8.0 or higher, powering the core backend functionality.
|
||||
</Card>
|
||||
|
||||
<Card title="Laravel" icon="laravel" href="https://laravel.com/" horizontal>
|
||||
The PHP framework that powers the backend of OpnForm.
|
||||
</Card>
|
||||
|
||||
## Database
|
||||
|
||||
<Card title="SQL Database" icon="database" href="https://en.wikipedia.org/wiki/SQL" horizontal>
|
||||
Supports relational database management systems like MySQL/MariaDB and PostgreSQL.
|
||||
</Card>
|
||||
|
||||
## Frontend
|
||||
|
||||
<Card title="Vue.js 3" icon="vuejs" href="https://v3.vuejs.org/" horizontal>
|
||||
The progressive JavaScript framework used for building the user interface.
|
||||
</Card>
|
||||
|
||||
<Card title="Nuxt.js" icon="mountains" href="https://nuxt.com/" horizontal>
|
||||
The Vue.js framework that enables server-side rendering and other powerful features.
|
||||
</Card>
|
||||
|
||||
<Card title="TailwindCSS" icon="wind" href="https://tailwindcss.com/" horizontal>
|
||||
A utility-first CSS framework for rapidly building custom user interfaces.
|
||||
</Card>
|
||||
|
||||
## Asset Compilation
|
||||
|
||||
<Card title="Node.js" icon="node-js" href="https://nodejs.org/" horizontal>
|
||||
Used for running JavaScript tools in the development environment.
|
||||
</Card>
|
||||
|
||||
<Card title="NPM" icon="npm" href="https://www.npmjs.com/" horizontal>
|
||||
Package manager for installing and managing frontend dependencies.
|
||||
</Card>
|
||||
|
||||
## Additional Technologies
|
||||
|
||||
<Card title="Docker" icon="docker" href="https://www.docker.com/" horizontal>
|
||||
Containerization platform used for easy deployment and development setup.
|
||||
</Card>
|
||||
|
||||
<Card title="Redis" icon="layer-group" href="https://redis.io/" horizontal>
|
||||
In-memory data structure store, used for caching and as a message broker.
|
||||
</Card>
|
||||
|
||||
<Card title="AWS S3" icon="bucket" href="https://aws.amazon.com/s3/" horizontal>
|
||||
Used for file storage (or compatible alternatives).
|
||||
</Card>
|
||||
|
||||
This tech stack allows OpnForm to deliver a fast, responsive, and feature-rich form building experience. For detailed installation instructions and system requirements, please refer to our [Docker deployment guide](deployment/docker) or [Local deployment guide](deployment/local-deployment).
|
||||
|
||||