Skip to content

Commit 10e5042

Browse files
authored
docs: adds comprehensive virtual field configuration documentation (#13942)
### What? Updated the existing Virtual Fields section to focus on Join field types and added a new "Virtual Field Configuration" section covering how to make any field virtual. ### Why? The existing virtual fields documentation was lacking depth and clarity. ### How? - Refined existing h3 "Virtual Fields" section to focus specifically on Join field types - Added new h2 "Virtual Field Configuration" section with detailed coverage of: - Boolean virtual fields with hooks for computed values - String path virtual fields for relationship resolution - Virtual path syntax and requirements - Common use cases with practical examples
1 parent 1510e12 commit 10e5042

File tree

2 files changed

+168
-65
lines changed

2 files changed

+168
-65
lines changed

docs/fields/overview.mdx

Lines changed: 143 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ Here are the available Presentational Fields:
101101

102102
### Virtual Fields
103103

104-
Virtual fields are used to display data that is not stored in the database. They are useful for displaying computed values that populate within the API response through hooks, etc.
104+
Virtual fields display data that is not stored in the database, but is computed or derived from other fields.
105105

106106
Here are the available Virtual Fields:
107107

@@ -115,6 +115,148 @@ Here are the available Virtual Fields:
115115
effectively create your own field type.
116116
</Banner>
117117

118+
## Virtual Field Configuration
119+
120+
While [Join fields](#virtual-fields) are purpose-built virtual field types, **any field type can be made virtual** by adding the `virtual` property to its configuration. This allows you to create computed or relationship-derived fields that appear in API responses without being stored in the database.
121+
122+
Virtual fields are populated during API responses and can be used in the Admin Panel, but their values are not persisted to the database. This makes them ideal for displaying read-only computed data, relationship summaries, or formatted versions of existing field data.
123+
124+
### Configuring Virtual Fields
125+
126+
Any field type can be made virtual by adding the `virtual` property to the field configuration. The `virtual` property can be configured in two ways:
127+
128+
#### Boolean Virtual Fields
129+
130+
When `virtual` is set to `true`, the field becomes virtual but doesn't automatically populate any data. You'll typically use [Field-level Hooks](#field-level-hooks) to compute and populate the field's value:
131+
132+
```ts
133+
{
134+
name: 'fullName',
135+
type: 'text',
136+
virtual: true,
137+
hooks: {
138+
afterRead: [
139+
({ siblingData }) => {
140+
return `${siblingData.firstName} ${siblingData.lastName}`
141+
}
142+
]
143+
}
144+
}
145+
```
146+
147+
#### String Path Virtual Fields
148+
149+
When `virtual` is set to a string path, it creates a "virtual relationship field" that automatically resolves to data from another field in the document. This is particularly useful for displaying relationship data:
150+
151+
```ts
152+
{
153+
name: 'authorName',
154+
type: 'text',
155+
virtual: 'author.name' // Resolves to the 'name' field of the 'author' relationship
156+
}
157+
```
158+
159+
### Virtual Path Syntax
160+
161+
Virtual paths use dot notation to traverse relationships and nested data:
162+
163+
- `author.name` - Gets the `name` field from the `author` relationship
164+
- `author.profile.bio` - Gets the `bio` field from a nested `profile` object within the `author` relationship
165+
- `categories.title` - For hasMany relationships, returns an array of `title` values
166+
- `request.additionalStakeholders.email` - Traverses multiple relationship levels
167+
168+
**Important Requirements for Virtual Path Fields:**
169+
170+
1. **Source Relationship Required**: The document must have a relationship field that corresponds to the first part of the virtual path. For example, if using `virtual: 'author.name'`, there must be an `author` relationship field defined in the same collection.
171+
172+
2. **Path Resolution**: Virtual paths resolve at query time by following the relationships and extracting the specified field values.
173+
174+
3. **Array Handling**: When the virtual path traverses a `hasMany` relationship, the result will be an array of values.
175+
176+
### Common Use Cases
177+
178+
#### Displaying Relationship Names
179+
180+
Instead of just showing relationship IDs, display the actual names or titles:
181+
182+
```ts
183+
// Original relationship field
184+
{
185+
name: 'author',
186+
type: 'relationship',
187+
relationTo: 'users'
188+
},
189+
// Virtual field to display author's name
190+
{
191+
name: 'authorName',
192+
type: 'text',
193+
virtual: 'author.name'
194+
}
195+
```
196+
197+
#### Multiple Relationship Values
198+
199+
For `hasMany` relationships, virtual fields return arrays:
200+
201+
```ts
202+
// Original relationship field
203+
{
204+
name: 'categories',
205+
type: 'relationship',
206+
relationTo: 'categories',
207+
hasMany: true
208+
},
209+
// Virtual field to display category titles
210+
{
211+
name: 'categoryTitles',
212+
type: 'text',
213+
virtual: 'categories.title' // Returns ['Tech', 'News', 'Updates']
214+
}
215+
```
216+
217+
#### Computed Values
218+
219+
Use hooks to create computed virtual fields:
220+
221+
```ts
222+
{
223+
name: 'wordCount',
224+
type: 'number',
225+
virtual: true,
226+
hooks: {
227+
afterRead: [
228+
({ siblingData }) => {
229+
const content = siblingData.content || ''
230+
return content.split(/\s+/).length
231+
}
232+
]
233+
}
234+
}
235+
```
236+
237+
### Virtual Fields in API Responses
238+
239+
Virtual fields appear in API responses alongside regular fields:
240+
241+
```json
242+
{
243+
"id": "123",
244+
"title": "My Post",
245+
"author": "64f1234567890abcdef12345",
246+
"authorName": "John Doe", // Virtual field
247+
"categories": ["64f9876543210fedcba67890", "64f5432109876543210abcdef"],
248+
"categoryTitles": ["Tech", "News"], // Virtual field
249+
"wordCount": 450 // Virtual field
250+
}
251+
```
252+
253+
<Banner type="warning">
254+
**Important:** When using virtual path fields, ensure that the referenced
255+
relationship field exists in your schema. Virtual paths like `author.name`
256+
require an `author` relationship field to be defined, otherwise the virtual
257+
field will not resolve properly.
258+
</Banner>
259+
118260
## Field Options
119261

120262
All fields require at least the `type` property. This matches the field to its corresponding [Field Type](#field-types) to determine its appearance and behavior within the [Admin Panel](../admin/overview). Each Field Type has its own unique set of options based on its own type.

0 commit comments

Comments
 (0)