Relations
strapi2front provides full support for Strapi relations, including the advanced relation API introduced in Strapi v5.
Relation Types
Section titled “Relation Types”Strapi supports several relation types:
| Type | Description | TypeScript |
|---|---|---|
oneToOne | Single relation, single target | Author | undefined |
manyToOne | Multiple sources, single target | Category | undefined |
oneToMany | Single source, multiple targets | Comment[] | undefined |
manyToMany | Multiple sources, multiple targets | Tag[] | undefined |
Reading Relations
Section titled “Reading Relations”Relations must be explicitly populated to be included in responses:
// Without population - relations are undefinedconst article = await articleService.findOne("abc123");console.log(article.author); // undefined
// With population - relations are loadedconst article = await articleService.findOne("abc123", { populate: ["author", "categories"],});console.log(article.author); // { id: 1, name: "John", ... }Nested Population
Section titled “Nested Population”Load nested relations:
const article = await articleService.findOne("abc123", { populate: { author: { populate: ["avatar", "company"], }, categories: { fields: ["name", "slug"], }, },});Writing Relations
Section titled “Writing Relations”Simple Format
Section titled “Simple Format”The simplest way to set relations is using document IDs:
// Single relationawait articleService.create({ title: "New Article", author: "authorDocumentId",});
// Multiple relationsawait articleService.create({ title: "New Article", categories: ["cat1", "cat2", "cat3"],});Advanced Relations (Strapi v5)
Section titled “Advanced Relations (Strapi v5)”Enable advanced relations in your config:
schemaOptions: { advancedRelations: true,}Connect
Section titled “Connect”Add relations while preserving existing ones:
await articleService.update("abc123", { categories: { connect: ["newCat1", "newCat2"], },});Disconnect
Section titled “Disconnect”Remove specific relations:
await articleService.update("abc123", { categories: { disconnect: ["catToRemove"], },});Replace all relations (removes existing, adds new):
await articleService.update("abc123", { categories: { set: ["onlyCat1", "onlyCat2"], },});Combining Connect and Disconnect
Section titled “Combining Connect and Disconnect”await articleService.update("abc123", { categories: { connect: ["newCat"], disconnect: ["oldCat"], },});Relation Ordering
Section titled “Relation Ordering”Control the order of relations using position:
// Add after specific itemawait articleService.update("abc123", { categories: { connect: [{ documentId: "newCat", position: { after: "existingCat" }, }], },});// Add before specific itemawait articleService.update("abc123", { categories: { connect: [{ documentId: "newCat", position: { before: "existingCat" }, }], },});// Add at startawait articleService.update("abc123", { categories: { connect: [{ documentId: "firstCat", position: { start: true }, }], },});
// Add at endawait articleService.update("abc123", { categories: { connect: [{ documentId: "lastCat", position: { end: true }, }], },});i18n Relations
Section titled “i18n Relations”Connect to specific localized versions:
await articleService.update("abc123", { relatedArticles: { connect: [{ documentId: "relatedId", locale: "es", // Connect to Spanish version }], },});Draft & Publish Relations
Section titled “Draft & Publish Relations”Connect to specific publication states:
await articleService.update("abc123", { relatedArticles: { connect: [{ documentId: "relatedId", status: "published", // Only connect to published version }], },});
// Connect to draft versionawait articleService.update("abc123", { relatedArticles: { connect: [{ documentId: "draftId", status: "draft", }], },});Full Example
Section titled “Full Example”Complete example with all advanced relation features:
await articleService.update("abc123", { // Replace all tags tags: { set: ["tag1", "tag2", "tag3"], },
// Modify categories (connect + disconnect) categories: { connect: [ { documentId: "newCat", position: { start: true } }, { documentId: "anotherCat", position: { after: "newCat" } }, ], disconnect: ["oldCat"], },
// Connect to localized content relatedArticles: { connect: [ { documentId: "spanishArticle", locale: "es" }, { documentId: "publishedOnly", status: "published" }, ], },});Form Handling
Section titled “Form Handling”With advanced relations enabled, your forms can handle complex relation updates:
function EditArticleCategories({ article, allCategories }) { const form = useForm({ resolver: zodResolver(articleUpdateSchema), defaultValues: { categories: article.categories?.map(c => c.documentId) || [], }, });
const onSubmit = async (data) => { const currentIds = article.categories?.map(c => c.documentId) || []; const newIds = data.categories;
// Calculate connect/disconnect const toConnect = newIds.filter(id => !currentIds.includes(id)); const toDisconnect = currentIds.filter(id => !newIds.includes(id));
await articleService.update(article.documentId, { categories: { connect: toConnect, disconnect: toDisconnect, }, }); };
return ( <form onSubmit={form.handleSubmit(onSubmit)}> {/* Multi-select for categories */} </form> );}Strapi v4 vs v5
Section titled “Strapi v4 vs v5”| Feature | Strapi v4 | Strapi v5 |
|---|---|---|
| Simple relations | id or [id] | documentId or [documentId] |
| Connect/Disconnect | Limited | Full support |
| Position ordering | No | Yes |
| i18n in relations | No | Yes |
| Status in relations | No | Yes |
strapi2front generates appropriate schemas based on your Strapi version.