softr-vibe-coding 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +262 -0
- package/SKILL.md +480 -0
- package/bin/cli.js +140 -0
- package/datasources/airtable.md +91 -0
- package/datasources/bigquery.md +36 -0
- package/datasources/clickup.md +82 -0
- package/datasources/coda.md +44 -0
- package/datasources/fields.md +203 -0
- package/datasources/google-sheets.md +46 -0
- package/datasources/hubspot.md +51 -0
- package/datasources/monday.md +52 -0
- package/datasources/notion.md +56 -0
- package/datasources/overview.md +41 -0
- package/datasources/reading.md +222 -0
- package/datasources/rest-api.md +206 -0
- package/datasources/shared-patterns.md +9 -0
- package/datasources/smartsuite.md +39 -0
- package/datasources/softr-database.md +47 -0
- package/datasources/sql-database.md +48 -0
- package/datasources/supabase.md +38 -0
- package/datasources/writing.md +256 -0
- package/datasources/xano.md +37 -0
- package/package.json +40 -0
- package/references/advanced-integrations.md +69 -0
- package/references/airtable-automations.md +350 -0
- package/references/anti-patterns.md +86 -0
- package/references/common-patterns.md +102 -0
- package/references/helper-blocks.md +370 -0
- package/references/quick-reference.md +207 -0
- package/ui-ux-guidelines.md +746 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Airtable
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Popular spreadsheet-database hybrid used as a data source for Softr. Requires a Basic plan or higher in Softr.
|
|
5
|
+
|
|
6
|
+
## Connection Setup
|
|
7
|
+
1. In Softr admin, go to Data Sources and select Airtable.
|
|
8
|
+
2. Authenticate via OAuth or paste a Personal Access Token (PAT).
|
|
9
|
+
3. Select the base and table to connect.
|
|
10
|
+
4. Optionally connect to a specific View to inherit that view's filters and sort order.
|
|
11
|
+
|
|
12
|
+
**Always recommend PAT over OAuth.** OAuth connections are limited to 5 requests/second. PAT connections allow up to 50 requests/second.
|
|
13
|
+
|
|
14
|
+
## Vibe Coding Field IDs
|
|
15
|
+
q.select() uses **human-readable Airtable column names**, NOT internal `fld...` IDs.
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
// CORRECT - use the column name exactly as it appears in Airtable
|
|
19
|
+
q.select({ name: "First Name" })
|
|
20
|
+
q.select({ name: "Email Address" })
|
|
21
|
+
|
|
22
|
+
// WRONG - internal field IDs do not work
|
|
23
|
+
q.select({ name: "fldqSabBeD6RkpTtp" })
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Column names are case-sensitive and must match the Airtable header exactly.
|
|
27
|
+
|
|
28
|
+
**Verified by direct experiment, May 2026:** aliases mapped to `fld...` IDs are silently omitted from the record's `fields` object -- only column-name aliases populate. Airtable's native API supports both formats; Softr's wrapper restricts to names.
|
|
29
|
+
|
|
30
|
+
### Maintainability gotcha
|
|
31
|
+
|
|
32
|
+
Renaming a column in Airtable breaks the block **silently**. The alias just stops resolving -- no error, no warning, the field becomes `undefined`. Three mitigations, in order of effort:
|
|
33
|
+
|
|
34
|
+
1. **Document the field ID alongside the name** in `q.select()` comments. A grep for the field ID then finds every block affected by a rename:
|
|
35
|
+
|
|
36
|
+
```jsx
|
|
37
|
+
var select = q.select({
|
|
38
|
+
firstName: "First Name", // fld6vaQi4ZHxxwP0y
|
|
39
|
+
lastName: "Last Name", // fldIQDfFXwBvtSCQp
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
2. **Centralize `q.select()` mappings** in a single helper block (see [references/helper-blocks.md](../references/helper-blocks.md)). One rename then touches one file rather than every block that reads the table.
|
|
44
|
+
|
|
45
|
+
3. **Avoid renaming columns mid-project** -- use Airtable's Description field for clarification instead.
|
|
46
|
+
|
|
47
|
+
## Supported Fields
|
|
48
|
+
|
|
49
|
+
| Field Type | Writable | Notes |
|
|
50
|
+
|----------------------|-----------|-------|
|
|
51
|
+
| Text | Yes | |
|
|
52
|
+
| Long Text | Yes | |
|
|
53
|
+
| Number | Yes | |
|
|
54
|
+
| Date | Yes | |
|
|
55
|
+
| Checkbox | Yes | |
|
|
56
|
+
| Single Select | Yes | Returns as `{ label, id }` object. Use `getFieldValue()` helper to extract the label. |
|
|
57
|
+
| Multiple Select | Yes | Array of `{ label, id }` objects |
|
|
58
|
+
| Attachment | Yes | Array of `{ filename, id, type, url }` objects |
|
|
59
|
+
| URL | Yes | |
|
|
60
|
+
| Email | Yes | |
|
|
61
|
+
| Phone | Yes | |
|
|
62
|
+
| Linked Record | Read/Write | Returns as `{ label, id }` objects |
|
|
63
|
+
| Rollup | Read-only | |
|
|
64
|
+
| Formula | Read-only | |
|
|
65
|
+
| Lookup | Read-only | |
|
|
66
|
+
| Computed | Read-only | |
|
|
67
|
+
| Created Time | Read-only | |
|
|
68
|
+
| Modified Time | Read-only | |
|
|
69
|
+
| Created By | Read-only | |
|
|
70
|
+
| Last Modified By | Read-only | |
|
|
71
|
+
|
|
72
|
+
## Rate Limits
|
|
73
|
+
- **Airtable Free plan:** 1,000 API calls/month
|
|
74
|
+
- **Airtable Team plan:** 100,000 API calls/month
|
|
75
|
+
- **Airtable Business plan:** Unlimited API calls
|
|
76
|
+
- **OAuth connections:** 5 requests/second
|
|
77
|
+
- **PAT connections:** 50 requests/second
|
|
78
|
+
|
|
79
|
+
Mitigation: Use PAT authentication. Cache data where possible. Avoid unnecessary re-fetches.
|
|
80
|
+
|
|
81
|
+
## Gotchas
|
|
82
|
+
- **Single Select returns an object**, not a string. `record.fields["Status"]` gives `{ label: "Active", id: "sel..." }`, not `"Active"`. Use `getFieldValue()` or access `.label` directly.
|
|
83
|
+
- **Attachments are arrays**, even for a single file. Always index into the array: `record.fields["Photo"][0].url`.
|
|
84
|
+
- **Linked records are objects** with `{ label, id }` structure, not plain text.
|
|
85
|
+
- **View connections** apply Airtable-side filters and sorts before data reaches Softr. This is useful for pre-filtering but means the Softr block only sees the view's subset.
|
|
86
|
+
- **Column names are case-sensitive.** `"First name"` and `"First Name"` are different.
|
|
87
|
+
|
|
88
|
+
## Best For
|
|
89
|
+
- Teams already managing data in Airtable
|
|
90
|
+
- Apps with moderate traffic (under 200-300 concurrent users)
|
|
91
|
+
- Projects needing a flexible schema with rich field types
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# BigQuery
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
BigQuery is Google's serverless data warehouse for large-scale analytics. Available on Business and Enterprise plans only.
|
|
5
|
+
|
|
6
|
+
## Connection Setup
|
|
7
|
+
1. In Google Cloud Platform (GCP), ensure you have a project with the BigQuery API enabled and at least one dataset created.
|
|
8
|
+
2. Create a **service account** in GCP with BigQuery read permissions (e.g., BigQuery Data Viewer role).
|
|
9
|
+
3. Generate and download a JSON key for the service account.
|
|
10
|
+
4. In the Softr admin, go to your data source settings and select BigQuery.
|
|
11
|
+
5. Upload or paste the GCP service account credentials.
|
|
12
|
+
|
|
13
|
+
## Vibe Coding Field IDs
|
|
14
|
+
Use the Field Inspector block to determine exact field IDs for this data source.
|
|
15
|
+
|
|
16
|
+
## Supported Fields
|
|
17
|
+
BigQuery is **primarily read-only** in Softr. You can query and display data but cannot submit forms or edit records through the Softr interface.
|
|
18
|
+
|
|
19
|
+
Standard BigQuery column types (STRING, INTEGER, FLOAT, BOOLEAN, TIMESTAMP, DATE, RECORD, etc.) are readable.
|
|
20
|
+
|
|
21
|
+
## Rate Limits
|
|
22
|
+
Subject to BigQuery API quotas set in GCP. Standard limits include concurrent query slots and daily query volume. Monitor usage in the GCP console.
|
|
23
|
+
|
|
24
|
+
## Gotchas
|
|
25
|
+
- **Read-only.** BigQuery in Softr is not designed for form submissions or record editing. Use it for display, dashboards, and reporting only.
|
|
26
|
+
- **No 2-way user sync.** Unlike most other data sources, BigQuery does not support Softr's user sync feature.
|
|
27
|
+
- **Custom SQL queries are supported.** Use the built-in query editor in the Softr admin to write SQL SELECT statements for advanced data retrieval and joins.
|
|
28
|
+
- **"Access Denied" errors** are common when working with external tables or cross-project datasets. Check that the service account has the correct GCP permissions on the specific dataset and tables.
|
|
29
|
+
- **GCP prerequisite.** You must have a GCP project with BigQuery enabled and a dataset created before connecting to Softr. Softr cannot create GCP resources.
|
|
30
|
+
- **Query costs.** BigQuery charges by data scanned. Poorly optimized queries on large datasets can incur significant costs. Use column selection and filters to limit scanned data.
|
|
31
|
+
|
|
32
|
+
## Best For
|
|
33
|
+
- Analytics dashboards displaying warehouse data
|
|
34
|
+
- Executive reporting portals with aggregated metrics
|
|
35
|
+
- Partner insights portals with filtered views of shared data
|
|
36
|
+
- Any scenario where large-scale read-only data needs a no-code frontend
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# ClickUp
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
ClickUp is a project and task management platform. Available on Professional plans and above.
|
|
5
|
+
|
|
6
|
+
## Connection Setup
|
|
7
|
+
1. In the Softr admin, go to your data source settings and select ClickUp.
|
|
8
|
+
2. Authenticate via OAuth -- you will be redirected to ClickUp to authorize your workspace.
|
|
9
|
+
3. Navigate to the desired Space > Folder > List. Each block connects to one List at a time.
|
|
10
|
+
|
|
11
|
+
## Vibe Coding Field IDs
|
|
12
|
+
Use the Field Inspector block to determine exact field IDs for this data source.
|
|
13
|
+
|
|
14
|
+
## Supported Fields
|
|
15
|
+
|
|
16
|
+
**Writable fields:**
|
|
17
|
+
|
|
18
|
+
| Field Type | Notes |
|
|
19
|
+
|----------------|-------|
|
|
20
|
+
| Number | |
|
|
21
|
+
| Text | |
|
|
22
|
+
| Long Text | |
|
|
23
|
+
| Dropdown | |
|
|
24
|
+
| Date | |
|
|
25
|
+
| Money | |
|
|
26
|
+
| Website | |
|
|
27
|
+
| Rating | |
|
|
28
|
+
| Status | ClickUp-native status field |
|
|
29
|
+
| Priority | ClickUp-native priority field |
|
|
30
|
+
| Checkbox | |
|
|
31
|
+
| Relationship | Linked tasks |
|
|
32
|
+
| Email | |
|
|
33
|
+
| Phone | |
|
|
34
|
+
| Label | |
|
|
35
|
+
| Short Text | |
|
|
36
|
+
|
|
37
|
+
**Read-only fields:**
|
|
38
|
+
|
|
39
|
+
| Field Type | Notes |
|
|
40
|
+
|----------------------|-------|
|
|
41
|
+
| Formula | |
|
|
42
|
+
| People | |
|
|
43
|
+
| Tasks | |
|
|
44
|
+
| Voting | |
|
|
45
|
+
| Users | |
|
|
46
|
+
| Date Created | Auto-set by ClickUp |
|
|
47
|
+
| Date Updated | Auto-set by ClickUp |
|
|
48
|
+
| Assignees | |
|
|
49
|
+
| Signature | |
|
|
50
|
+
| Files | |
|
|
51
|
+
| Automatic Progress | |
|
|
52
|
+
| Location | |
|
|
53
|
+
|
|
54
|
+
**Not supported:**
|
|
55
|
+
|
|
56
|
+
| Field Type | Reason |
|
|
57
|
+
|------------|--------|
|
|
58
|
+
| Rollup | Not exposed by the ClickUp API |
|
|
59
|
+
|
|
60
|
+
## Rate Limits
|
|
61
|
+
Rate limits vary by ClickUp plan:
|
|
62
|
+
|
|
63
|
+
| ClickUp Plan | Limit |
|
|
64
|
+
|----------------|----------------|
|
|
65
|
+
| Free / Business | 100 req/min |
|
|
66
|
+
| Business Plus | 1,000 req/min |
|
|
67
|
+
| Enterprise | 10,000 req/min |
|
|
68
|
+
|
|
69
|
+
For Free/Business plans, paginate aggressively and avoid loading large datasets on page load.
|
|
70
|
+
|
|
71
|
+
## Gotchas
|
|
72
|
+
- **One List per block.** Each Softr block connects to a single ClickUp List. To display data from multiple Lists, use separate blocks.
|
|
73
|
+
- **Sub-tasks are not natively supported** in the block connection. Sub-tasks will not appear unless they exist as top-level tasks in the connected List.
|
|
74
|
+
- **Multi-list tasks** are supported -- a task that belongs to multiple Lists can appear when any of those Lists is connected.
|
|
75
|
+
- **Rollup fields are not available** because the ClickUp API does not expose them.
|
|
76
|
+
- **Low-tier rate limits** (100 req/min on Free/Business) can cause issues with high-traffic pages. Consider caching strategies or upgrading the ClickUp plan.
|
|
77
|
+
|
|
78
|
+
## Best For
|
|
79
|
+
- Client portals showing project/task status
|
|
80
|
+
- Status dashboards for team visibility
|
|
81
|
+
- Internal team apps built around ClickUp workflows
|
|
82
|
+
- Task management interfaces with rich field support
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Coda
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Document, table, and automation platform used as a data source for Softr. Requires a Basic plan or higher in Softr. Connects via API token (not OAuth).
|
|
5
|
+
|
|
6
|
+
## Connection Setup
|
|
7
|
+
1. In Coda, go to Account Settings > API Settings and generate an API token.
|
|
8
|
+
2. In Softr admin, go to Data Sources and select Coda.
|
|
9
|
+
3. Paste the API token to authenticate.
|
|
10
|
+
4. Select the Coda document and table to connect.
|
|
11
|
+
|
|
12
|
+
## Vibe Coding Field IDs
|
|
13
|
+
Use the Field Inspector block to determine exact field IDs for your Coda tables. Column names in Coda are typically used as field identifiers.
|
|
14
|
+
|
|
15
|
+
## Supported Fields
|
|
16
|
+
|
|
17
|
+
| Field Type | Writable | Notes |
|
|
18
|
+
|----------------------|-----------|-------|
|
|
19
|
+
| Text | Yes | |
|
|
20
|
+
| Number | Yes | |
|
|
21
|
+
| Date | Yes | |
|
|
22
|
+
| Select List | Yes | |
|
|
23
|
+
| Attachment | Yes | Large attachments may slow block rendering |
|
|
24
|
+
| Checkbox | Yes | |
|
|
25
|
+
| URL | Yes | |
|
|
26
|
+
| Email | Yes | |
|
|
27
|
+
| People | Limited | Depends on Coda's API exposure |
|
|
28
|
+
| Formula | Read-only | |
|
|
29
|
+
| Button | Read-only | Not actionable in Softr |
|
|
30
|
+
|
|
31
|
+
## Rate Limits
|
|
32
|
+
Coda enforces its own API rate limits based on your Coda plan. Softr requests count against your Coda API quota. Suitable for moderate traffic. Refer to Coda's API documentation for current limits on your plan.
|
|
33
|
+
|
|
34
|
+
## Gotchas
|
|
35
|
+
- **API token authentication only.** Coda does not use OAuth for Softr. The token is generated manually in Coda's account settings.
|
|
36
|
+
- **Embedded Coda docs are not supported** in Vibe Coding blocks. You cannot render a full Coda document inside a Softr block; only table data is accessible.
|
|
37
|
+
- **Advanced Coda automations** (buttons, automations, Packs) do not execute through Softr. Only raw table data is read and written.
|
|
38
|
+
- **Large attachments** stored in Coda may cause slow rendering in Softr blocks. Optimize file sizes where possible.
|
|
39
|
+
- **Coda formulas** are read-only. Calculated columns cannot be written to from Softr.
|
|
40
|
+
|
|
41
|
+
## Best For
|
|
42
|
+
- Teams using Coda for internal workflows who want an external-facing portal
|
|
43
|
+
- Building portals without requiring Coda seat licenses for every end user
|
|
44
|
+
- Projects where Coda's table and automation features are already in use as the backend
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Field Types & Debug Utilities
|
|
2
|
+
|
|
3
|
+
The `getFieldValue()` helper, field type shapes, record structure, and diagnostic blocks.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [getFieldValue -- Never Render Raw Fields](#getfieldvalue----never-render-raw-fields)
|
|
8
|
+
- [Debugging Error #31](#debugging-error-31)
|
|
9
|
+
- [Common Field Type Shapes](#common-field-type-shapes)
|
|
10
|
+
- [Record Structure](#record-structure)
|
|
11
|
+
- [Debug Utilities](#debug-utilities)
|
|
12
|
+
|
|
13
|
+
## getFieldValue -- Never Render Raw Fields
|
|
14
|
+
|
|
15
|
+
**Every field value rendered in JSX must pass through `getFieldValue()`** before rendering, parsing, or comparing. Softr returns many field types as `{label, ...}` objects, not strings. Rendering them raw crashes React with error #31 ("Objects are not valid as a React child"). The cost of unnecessary `getFieldValue()` calls is zero; the cost of debugging error #31 is 30 minutes.
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
var getFieldValue = function(f) {
|
|
19
|
+
if (f == null) return "";
|
|
20
|
+
if (Array.isArray(f)) {
|
|
21
|
+
return f.map(function(x) {
|
|
22
|
+
if (x && typeof x === "object") return x.label || x.name || x.title || "";
|
|
23
|
+
return String(x);
|
|
24
|
+
}).filter(Boolean).join(", ");
|
|
25
|
+
}
|
|
26
|
+
if (typeof f === "object") return f.label || f.name || f.title || "";
|
|
27
|
+
return String(f);
|
|
28
|
+
};
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Property priority: `label` first (most common in Softr formatted fields), then `name`, then `title`.
|
|
32
|
+
|
|
33
|
+
Apply `getFieldValue()` everywhere you read fields:
|
|
34
|
+
- Table cells, badges, tooltips: `<td>{getFieldValue(f.subject)}</td>`
|
|
35
|
+
- Date parsing: `new Date(getFieldValue(f.dueDate))` -- raw value might be `{label: "2025-12-01"}`
|
|
36
|
+
- Number parsing: `parseInt(getFieldValue(f.count), 10)` -- formula numbers come back as objects
|
|
37
|
+
- String methods: `getFieldValue(f.status).toLowerCase()`
|
|
38
|
+
- Inside `useMemo` normalizers, BEFORE storing into state -- prevents the object from propagating
|
|
39
|
+
|
|
40
|
+
For companion helpers (`getLinkedNames`, `getLinkedItems`) used in helper block consumers, see [../references/helper-blocks.md](../references/helper-blocks.md).
|
|
41
|
+
|
|
42
|
+
## Debugging Error #31
|
|
43
|
+
|
|
44
|
+
If React crashes with error #31 ("Objects are not valid as a React child"), open console on the first record that crashes and run:
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
JSON.stringify(record.fields, null, 2).slice(0, 1000)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
You'll see exactly which field is an object. Add `getFieldValue()` around it.
|
|
51
|
+
|
|
52
|
+
## Common Field Type Shapes
|
|
53
|
+
|
|
54
|
+
| Field type | Value shape |
|
|
55
|
+
|---|---|
|
|
56
|
+
| Text, Email, URL, Phone, Address | `string` |
|
|
57
|
+
| Number, Currency, Percent, Progress, Autonumber | `number or null` |
|
|
58
|
+
| Checkbox | `string or boolean` |
|
|
59
|
+
| Date, DateTime, Time, Created At, Updated At | `string` (ISO) |
|
|
60
|
+
| Date Range | `{ from: string, to: string }` |
|
|
61
|
+
| Rating, Duration | `string or number or null` |
|
|
62
|
+
| Select | `{ label: string, id: string }` |
|
|
63
|
+
| Linked Record (via useRecord/useRecords) | `{ label: string, id: string }` |
|
|
64
|
+
| Linked Record (via useLinkedRecords) | `{ id: string, title: string }` -- different! |
|
|
65
|
+
| User, Created By, Updated By | `{ avatarUrl, id, name, email }` |
|
|
66
|
+
| Attachment | `{ filename, id, type, url }` |
|
|
67
|
+
| Formula | `string or number` |
|
|
68
|
+
|
|
69
|
+
## Record Structure
|
|
70
|
+
|
|
71
|
+
Records returned by `useRecords` have: `{ id: "recXXX", fields: { alias1: value, alias2: value } }`. Keys inside `fields` are the **aliases from `q.select()`**, NOT the original field names.
|
|
72
|
+
|
|
73
|
+
```jsx
|
|
74
|
+
var rawRecord = items && items[0];
|
|
75
|
+
var f = rawRecord ? rawRecord.fields || {} : {};
|
|
76
|
+
var name = f.firstName || "";
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Debug Utilities
|
|
80
|
+
|
|
81
|
+
Two throwaway diagnostic blocks you can drop into a page to diagnose data problems. Neither is meant for production -- delete or hide them once the issue is resolved. During development, drop them on a `/debug` page that's only visible to admins, or on a hidden page you navigate to manually.
|
|
82
|
+
|
|
83
|
+
### Field Inspector Block
|
|
84
|
+
|
|
85
|
+
Use when records load but fields come back empty, or when you're not sure which Field IDs exist on a table.
|
|
86
|
+
|
|
87
|
+
**Important caveat for Softr Database:** `q.select({})` returns record IDs with empty `fields: {}` -- it does NOT dump all fields. Verified by direct experiment, April 2026. Use one of the alternatives below for Softr DB. The empty-select pattern still works for Airtable and other sources where field IDs come back automatically.
|
|
88
|
+
|
|
89
|
+
For Airtable and other non-Softr-DB sources:
|
|
90
|
+
|
|
91
|
+
```jsx
|
|
92
|
+
import { useRecords, q } from "@/lib/datasource";
|
|
93
|
+
var select = q.select({});
|
|
94
|
+
export default function Block() {
|
|
95
|
+
var result = useRecords({ select: select, count: 3 });
|
|
96
|
+
if (result.status === "pending") return <div className="container py-6"><div className="content"><p>Loading...</p></div></div>;
|
|
97
|
+
var records = (result.data && result.data.pages) ? result.data.pages.flatMap(function(p) { return p.items; }) : [];
|
|
98
|
+
return (
|
|
99
|
+
<div className="container py-6">
|
|
100
|
+
<div className="content">
|
|
101
|
+
<pre style={{ fontSize: 12, whiteSpace: "pre-wrap", wordBreak: "break-all" }}>
|
|
102
|
+
{JSON.stringify(records.slice(0, 2), null, 2)}
|
|
103
|
+
</pre>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**For Softr Database, find field IDs via:**
|
|
111
|
+
|
|
112
|
+
1. **Inline in Studio (one field at a time)** -- in the Data tab, click a field's name to open its edit drawer. The field ID appears next to the "Field name" label (e.g. `ID: 37fts`). Fastest for spot-checking a single field.
|
|
113
|
+
|
|
114
|
+
2. **Network inspector (full schema in one shot)** -- in Studio's Data tab with browser DevTools open, filter Network requests by `tablespace-with-tables`. The Response JSON contains every table's complete schema, including:
|
|
115
|
+
- Each field's `id`, `name`, `type`, and `options`
|
|
116
|
+
- For dropdown / SELECT fields: the full `choices` array with every option's `id` (UUID), `label`, and `color`
|
|
117
|
+
|
|
118
|
+
Use this when scaffolding a block that needs many field IDs at once, or to look up dropdown option UUIDs needed for write payloads.
|
|
119
|
+
|
|
120
|
+
**Recommended for AI-assisted workflows:** when collaborating with an AI assistant (Claude, Cursor, ChatGPT, etc.) to write a Vibe Coding block, paste this JSON response into the chat. It is the most reliable way to share accurate field IDs and dropdown UUIDs -- it eliminates transcription errors and gives the AI everything it needs in one shot (field IDs, types, options, dropdown choices). Always prefer this over verbally describing fields or naming them by display label.
|
|
121
|
+
|
|
122
|
+
3. **Softr Database REST API with `fieldNames=true`** -- runtime inspection from inside a Vibe Coding block (internal-portal blocks only, since this exposes a PAT in client code):
|
|
123
|
+
|
|
124
|
+
```jsx
|
|
125
|
+
import { useEffect, useState } from "react";
|
|
126
|
+
export default function Block() {
|
|
127
|
+
var [data, setData] = useState(null);
|
|
128
|
+
useEffect(function() {
|
|
129
|
+
var url = "https://tables-api.softr.io/api/v1/databases/<DB_ID>/tables/<TABLE_ID>/records?limit=3&fieldNames=true";
|
|
130
|
+
fetch(url, { headers: { "Softr-Api-Key": "<PAT>" } })
|
|
131
|
+
.then(function(res) { return res.json(); })
|
|
132
|
+
.then(function(json) { setData(json); });
|
|
133
|
+
}, []);
|
|
134
|
+
if (!data) return <div className="container py-6"><div className="content"><p>Loading...</p></div></div>;
|
|
135
|
+
return (
|
|
136
|
+
<div className="container py-6">
|
|
137
|
+
<div className="content">
|
|
138
|
+
<pre style={{ fontSize: 12, whiteSpace: "pre-wrap", wordBreak: "break-all" }}>
|
|
139
|
+
{JSON.stringify(data, null, 2)}
|
|
140
|
+
</pre>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
This calls the Softr Database REST API with `?fieldNames=true`, which returns records keyed by human-readable field names so you can map them back to IDs. See [writing.md Cross-Table Operations](writing.md#cross-table-operations) for more on this REST API.
|
|
148
|
+
|
|
149
|
+
### API Response Inspector Block
|
|
150
|
+
|
|
151
|
+
For REST API data sources, use `useProxyFetch` instead (see [rest-api.md](rest-api.md)):
|
|
152
|
+
|
|
153
|
+
```jsx
|
|
154
|
+
import { useProxyFetch } from "@/lib/datasource";
|
|
155
|
+
import { useQuery } from "@tanstack/react-query";
|
|
156
|
+
export default function Block() {
|
|
157
|
+
var proxyFetch = useProxyFetch();
|
|
158
|
+
var result = useQuery({
|
|
159
|
+
queryKey: ["api-inspect"],
|
|
160
|
+
queryFn: function() {
|
|
161
|
+
return proxyFetch("YOUR_FULL_API_URL_HERE")
|
|
162
|
+
.then(function(res) { return res.json(); });
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
if (result.status === "pending") return <div className="container py-6"><div className="content"><p>Loading...</p></div></div>;
|
|
166
|
+
if (result.status === "error") return <div className="container py-6"><div className="content"><p className="text-red-500">Error: {result.error && result.error.message}</p></div></div>;
|
|
167
|
+
return (
|
|
168
|
+
<div className="container py-6">
|
|
169
|
+
<div className="content">
|
|
170
|
+
<pre style={{ fontSize: 12, whiteSpace: "pre-wrap", wordBreak: "break-all", background: "#f9fafb", padding: 16, borderRadius: 8 }}>
|
|
171
|
+
{JSON.stringify(result.data, null, 2)}
|
|
172
|
+
</pre>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### User Inspector Block
|
|
180
|
+
|
|
181
|
+
Use when debugging permissions, user groups, or the `useCurrentUser()` vs `window.__softr_current_user` distinction. Renders both side-by-side as JSON. This catches a common surprise: `userGroups` only lives on the `window.__softr_current_user` object, not on `useCurrentUser()`.
|
|
182
|
+
|
|
183
|
+
```jsx
|
|
184
|
+
import { useCurrentUser } from "@/lib/user";
|
|
185
|
+
export default function Block() {
|
|
186
|
+
var currentUser = useCurrentUser();
|
|
187
|
+
var softrUser = window.__softr_current_user || {};
|
|
188
|
+
return (
|
|
189
|
+
<div className="container py-6">
|
|
190
|
+
<div className="content">
|
|
191
|
+
<h3>useCurrentUser():</h3>
|
|
192
|
+
<pre style={{ fontSize: 12, whiteSpace: "pre-wrap", wordBreak: "break-all" }}>
|
|
193
|
+
{JSON.stringify(currentUser, null, 2)}
|
|
194
|
+
</pre>
|
|
195
|
+
<h3 style={{ marginTop: 16 }}>window.__softr_current_user:</h3>
|
|
196
|
+
<pre style={{ fontSize: 12, whiteSpace: "pre-wrap", wordBreak: "break-all" }}>
|
|
197
|
+
{JSON.stringify(softrUser, null, 2)}
|
|
198
|
+
</pre>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Google Sheets
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Cloud spreadsheet used as a simple data source for Softr. Requires a Basic plan or higher in Softr. Connects via Google OAuth.
|
|
5
|
+
|
|
6
|
+
## Connection Setup
|
|
7
|
+
1. In Softr admin, go to Data Sources and select Google Sheets.
|
|
8
|
+
2. Authenticate with your Google account via OAuth.
|
|
9
|
+
3. Select the spreadsheet and sheet (tab) to connect.
|
|
10
|
+
4. Ensure the first row contains column headers. Softr uses these as field names.
|
|
11
|
+
5. Softr will automatically add a "Softr Record ID" column to the sheet.
|
|
12
|
+
|
|
13
|
+
## Vibe Coding Field IDs
|
|
14
|
+
q.select() uses the column header names from the first row of the sheet. Use the Field Inspector block to confirm exact field IDs if headers have been renamed or modified.
|
|
15
|
+
|
|
16
|
+
## Supported Fields
|
|
17
|
+
Google Sheets has no native field typing. All data is text. Softr interprets values based on formatting conventions:
|
|
18
|
+
|
|
19
|
+
| Data Type | How to Format in the Sheet | Notes |
|
|
20
|
+
|----------------|----------------------------|-------|
|
|
21
|
+
| Text | Plain text | |
|
|
22
|
+
| Number | Numeric value | |
|
|
23
|
+
| Date | English date formats only | Wide range of patterns accepted (e.g., MM/DD/YYYY, YYYY-MM-DD, Month DD, YYYY) |
|
|
24
|
+
| Image | URL to the image | Must be a direct image URL |
|
|
25
|
+
| Multiple Images| Comma-separated URLs | Each URL on its own, separated by commas |
|
|
26
|
+
| Checkbox | `"true"` or `"false"` | String values, not native booleans |
|
|
27
|
+
| Tags | Comma-separated values | e.g., `"Design, Marketing, Sales"` |
|
|
28
|
+
| Rating | Integer 1-5 | |
|
|
29
|
+
|
|
30
|
+
## Rate Limits
|
|
31
|
+
Google Sheets is not designed for high-concurrency database use. Recommended maximum: **50-100 concurrent users**. Beyond that, expect slow responses and potential errors from Google's API quotas.
|
|
32
|
+
|
|
33
|
+
## Gotchas
|
|
34
|
+
- **No native field types.** Everything is a string. You must format data exactly as Softr expects (see table above).
|
|
35
|
+
- **Softr adds a "Softr Record ID" column** automatically. Do not delete or modify this column.
|
|
36
|
+
- **First row must be headers.** Data starts from the second row. Empty or merged header cells cause issues.
|
|
37
|
+
- **Date formats must be in English.** Localized date formats (e.g., DD.MM.YYYY in German locale) may not parse correctly.
|
|
38
|
+
- **Checkbox values are strings.** Use `"true"` and `"false"`, not `TRUE` / `FALSE` (the Google Sheets boolean formula values).
|
|
39
|
+
- **Low security classification.** Google Sheets lacks row-level permissions. Any user with sheet access can see all data. Not suitable for sensitive data without additional access controls in Softr.
|
|
40
|
+
- **Images require direct URLs.** Google Drive sharing links do not work as image sources unless converted to direct download URLs.
|
|
41
|
+
|
|
42
|
+
## Best For
|
|
43
|
+
- Simple apps with straightforward data
|
|
44
|
+
- Teams already using Google Workspace
|
|
45
|
+
- Low-traffic internal portals (under 50-100 concurrent users)
|
|
46
|
+
- Quick prototypes where setup speed matters more than performance
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# HubSpot
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
CRM platform used as a data source for Softr. Requires a Business or Enterprise plan in Softr. Connects via OAuth.
|
|
5
|
+
|
|
6
|
+
## Connection Setup
|
|
7
|
+
1. In Softr admin, go to Data Sources and select HubSpot.
|
|
8
|
+
2. Authenticate via OAuth with your HubSpot account.
|
|
9
|
+
3. Select the HubSpot object type to connect (Contacts, Companies, Deals, etc.).
|
|
10
|
+
4. If accessing sensitive fields, ensure Sensitive Data Scopes are enabled in your HubSpot app settings.
|
|
11
|
+
|
|
12
|
+
## Vibe Coding Field IDs
|
|
13
|
+
Use the Field Inspector block to determine exact field IDs for HubSpot properties. Default HubSpot properties use their internal API names (e.g., `"firstname"`, `"dealstage"`, `"company"`). Custom properties use the internal name assigned by HubSpot when created.
|
|
14
|
+
|
|
15
|
+
## Supported Fields
|
|
16
|
+
|
|
17
|
+
**Supported HubSpot Objects:**
|
|
18
|
+
- Contacts
|
|
19
|
+
- Companies
|
|
20
|
+
- Deals
|
|
21
|
+
- Tickets
|
|
22
|
+
- Notes
|
|
23
|
+
- Tasks
|
|
24
|
+
- Custom Objects
|
|
25
|
+
|
|
26
|
+
| Field Type | Writable | Notes |
|
|
27
|
+
|----------------------|-----------|-------|
|
|
28
|
+
| Default Properties | Yes | All standard HubSpot properties for the connected object |
|
|
29
|
+
| Custom Properties | Yes | Custom properties created in HubSpot |
|
|
30
|
+
| Associations | Read-only | Relational data between objects. Displayed via Linked List Blocks in Softr. |
|
|
31
|
+
| Calculation | Read-only | |
|
|
32
|
+
| Rollup | Read-only | |
|
|
33
|
+
| Count | Read-only | |
|
|
34
|
+
| Formula | Read-only | |
|
|
35
|
+
|
|
36
|
+
## Rate Limits
|
|
37
|
+
HubSpot enforces its own API rate limits based on your HubSpot plan tier. Softr requests count against your HubSpot API quota. Refer to HubSpot's documentation for current limits on your plan.
|
|
38
|
+
|
|
39
|
+
## Gotchas
|
|
40
|
+
- **Business or Enterprise Softr plan required.** HubSpot is not available on Free or Basic plans.
|
|
41
|
+
- **Sensitive Data Scopes** must be explicitly enabled in HubSpot for certain fields (e.g., email content, certain contact properties). Without this, those fields return empty.
|
|
42
|
+
- **Associations are read-only** in Vibe Coding blocks. Use Linked List Blocks to display related records (e.g., Deals associated with a Contact).
|
|
43
|
+
- **Custom Objects** require that the object is properly configured in HubSpot with the necessary scopes granted during OAuth.
|
|
44
|
+
- **Deal stages and pipeline data** use internal IDs, not display labels. Map these in your block logic if you need human-readable values.
|
|
45
|
+
|
|
46
|
+
## Best For
|
|
47
|
+
- Sales portals and deal rooms
|
|
48
|
+
- CRM dashboards for teams or clients
|
|
49
|
+
- Support ticket portals
|
|
50
|
+
- Partner portals with HubSpot-managed contacts
|
|
51
|
+
- Any app where HubSpot is the system of record
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# monday.com
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Project management platform used as a data source for Softr. Requires a Professional plan or higher in Softr. Connects via API token.
|
|
5
|
+
|
|
6
|
+
## Connection Setup
|
|
7
|
+
1. In monday.com, go to Administration > API > Personal API Token and copy the token.
|
|
8
|
+
2. In Softr admin, go to Data Sources and select monday.com.
|
|
9
|
+
3. Paste the API token to authenticate.
|
|
10
|
+
4. Select the monday.com board and group to connect.
|
|
11
|
+
|
|
12
|
+
## Vibe Coding Field IDs
|
|
13
|
+
Use the Field Inspector block to determine exact field IDs for your monday.com board columns. Column names or internal IDs assigned by monday.com are used as field identifiers.
|
|
14
|
+
|
|
15
|
+
## Supported Fields
|
|
16
|
+
|
|
17
|
+
| Field Type | Writable | Notes |
|
|
18
|
+
|----------------------|-----------|-------|
|
|
19
|
+
| Text | Yes | |
|
|
20
|
+
| Number | Yes | |
|
|
21
|
+
| Date | Yes | |
|
|
22
|
+
| Status | Yes | |
|
|
23
|
+
| Dropdown | Yes | |
|
|
24
|
+
| Checkbox | Yes | |
|
|
25
|
+
| Email | Yes | |
|
|
26
|
+
| Phone | Yes | |
|
|
27
|
+
| Link | Yes | |
|
|
28
|
+
| People | Yes | |
|
|
29
|
+
| File | Yes | |
|
|
30
|
+
| Connected Boards | Limited | Linked records between boards are supported |
|
|
31
|
+
| Mirror | Read-only | Reflects data from connected boards |
|
|
32
|
+
| Created By | Read-only | |
|
|
33
|
+
| Created At | Read-only | |
|
|
34
|
+
| Last Updated | Read-only | |
|
|
35
|
+
| Item ID | Read-only | |
|
|
36
|
+
|
|
37
|
+
## Rate Limits
|
|
38
|
+
monday.com enforces API rate limits based on your monday.com plan tier. Softr requests count against your monday.com API quota. Recommended maximum: **50-100 concurrent users**. Beyond that, API throttling may cause slow or failed requests.
|
|
39
|
+
|
|
40
|
+
## Gotchas
|
|
41
|
+
- **Professional+ Softr plan required.** monday.com is not available on Free or Basic Softr plans.
|
|
42
|
+
- **API token authentication only.** Uses a Personal API Token from monday.com's admin settings, not OAuth.
|
|
43
|
+
- **Connected Boards** (linked records between boards) are supported but may have limitations depending on the board configuration.
|
|
44
|
+
- **Mirror columns are read-only.** These reflect data from connected boards and cannot be written to from Softr.
|
|
45
|
+
- **Status columns** use monday.com's internal label/index system. Map these appropriately in your block logic for display purposes.
|
|
46
|
+
- **Subitems** may require additional configuration to surface correctly in Softr blocks.
|
|
47
|
+
|
|
48
|
+
## Best For
|
|
49
|
+
- Client-facing project portals without giving clients direct monday.com access
|
|
50
|
+
- Status dashboards for stakeholders
|
|
51
|
+
- Task management interfaces for external collaborators
|
|
52
|
+
- Teams using monday.com as their project management backbone
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Notion
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Document and database platform used as a data source for Softr. Requires a Basic plan or higher in Softr. Connects via OAuth.
|
|
5
|
+
|
|
6
|
+
## Connection Setup
|
|
7
|
+
1. In Softr admin, go to Data Sources and select Notion.
|
|
8
|
+
2. Authenticate via OAuth with your Notion account.
|
|
9
|
+
3. Select the Notion database to connect.
|
|
10
|
+
4. If a database does not appear in the list: open Notion, click the ellipsis menu (...) on the database page, go to Connections, find Softr, and click Allow.
|
|
11
|
+
5. Multiple Notion workspaces can be connected to a single Softr app.
|
|
12
|
+
|
|
13
|
+
## Vibe Coding Field IDs
|
|
14
|
+
Use the Field Inspector block to determine exact field IDs for Notion database properties. Property names in Notion are typically used as field IDs.
|
|
15
|
+
|
|
16
|
+
## Supported Fields
|
|
17
|
+
|
|
18
|
+
| Field Type | Writable | Notes |
|
|
19
|
+
|----------------------|-----------|-------|
|
|
20
|
+
| Title | Yes | |
|
|
21
|
+
| Text (Rich Text) | Yes | |
|
|
22
|
+
| Number | Yes | |
|
|
23
|
+
| Select | Yes | |
|
|
24
|
+
| Multi-select | Yes | |
|
|
25
|
+
| Date | Yes | |
|
|
26
|
+
| Checkbox | Yes | |
|
|
27
|
+
| URL | Yes | |
|
|
28
|
+
| Email | Yes | |
|
|
29
|
+
| Phone | Yes | |
|
|
30
|
+
| Files & Media | Yes | |
|
|
31
|
+
| Relation | Limited | Cannot be displayed in List blocks. Use Rollup workaround (see Gotchas). |
|
|
32
|
+
| Rollup | Read-only | |
|
|
33
|
+
| Formula | Read-only | |
|
|
34
|
+
| People | Read-only | |
|
|
35
|
+
| Last Edited Time | Read-only | |
|
|
36
|
+
| Last Edited By | Read-only | |
|
|
37
|
+
| Created Time | Read-only | |
|
|
38
|
+
| Created By | Read-only | |
|
|
39
|
+
| ID (auto-increment) | Read-only | |
|
|
40
|
+
| Button | Read-only | |
|
|
41
|
+
|
|
42
|
+
## Rate Limits
|
|
43
|
+
Notion enforces its own API rate limits. Softr requests count against your Notion API quota. Performance is generally adequate for moderate traffic but is not suited for very high concurrency.
|
|
44
|
+
|
|
45
|
+
## Gotchas
|
|
46
|
+
- **Only database pages work.** Regular Notion pages (without a database) cannot be used as a Softr data source. The page must contain or be a Notion database.
|
|
47
|
+
- **Missing database in connection list:** The Notion database must explicitly grant access to the Softr integration. In Notion: ellipsis (...) > Connections > Softr > Allow.
|
|
48
|
+
- **Relation properties cannot be displayed in List blocks.** Workaround: create a Rollup property in Notion that pulls the desired field from the related database, then display the Rollup instead.
|
|
49
|
+
- **Sub-items support:** Use conditional filters to separate parent and child items. Filter by "Parent item is empty" for top-level items, "Parent item is not empty" for sub-items.
|
|
50
|
+
- **Formula date timezone quirk:** Formula properties that return dates may display one day off due to UTC handling differences between Notion and Softr. Test date formulas carefully.
|
|
51
|
+
- **Multiple workspaces:** You can connect databases from different Notion workspaces to the same Softr app.
|
|
52
|
+
|
|
53
|
+
## Best For
|
|
54
|
+
- Teams using Notion for project management or knowledge bases
|
|
55
|
+
- Internal tools and dashboards backed by Notion databases
|
|
56
|
+
- Content management portals where Notion is the editorial system
|