I'm using the [multi-tenant example](
https://github.com/payloadcms/payload/tree/main/examples/multi-tenant) and trying to set up livePreview on my Pages collection with a [dynamic URL](
https://payloadcms.com/docs/live-preview/overview#dynamic-urls) containing the tenant URL as documented.
The
url.dataparam returns all document's field/data, and
data.tenantis just the objectID of the Tenants collection doc, because the [tenantField](
https://github.com/payloadcms/payload/blob/main/examples/multi-tenant/src/collections/Pages/index.ts#L35) is [a relationship field](
https://github.com/payloadcms/payload/blob/main/examples/multi-tenant/src/fields/TenantField/index.ts#L9), and that will only [return the objectID by design](
https://payloadcms.com/docs/fields/relationship#has-one).
The tenant's objectID is not sufficient to construct the dynamic URL, as I actually need the [tenant's slug](
https://github.com/payloadcms/payload/blob/556b8ed393a0b8b6c1b4f6c80d76e3dcd9fe129b/examples/multi-tenant/src/collections/Tenants/index.ts#L41-L47).
My question is – what's the best way to get the tenant.slug in the
dataparam of the livePreview
urlfunction? Should I add another field to my Pages collection that gets the tenant slug from the relationship field's objectID? Or should I query the local API for the
tenant.slug? Is it even possible/advisable to run logic/query the API in the Payload config?
For some reason I'm having trouble making sense of the
reqparam inside the
urlfunction to see if I can extract the tenant slug from it somehow.
According to the docs you can use
data.tenant.urlin the
urlfunction, but
data.tenantis just a string with the objectID, so perhaps the docs are misleading.
Thanks!
I solved this with another field
tenantSlugthat simply reads the
tenantFieldand queries the local API to get the slug of the tenant.
{
name: 'tenantSlug',
type: 'text',
label: 'Tenant Slug',
admin: {
readOnly: true,
},
hooks: {
afterRead: [
async ({ req, data }) => {
const tenantId = data?.tenant;
if (!tenantId) return null;
const tenant = await req.payload.findByID({
collection: 'tenants',
id: tenantId
});
return tenant?.slug || null;
}
]
}
} livePreview: {
url: ({
data,
collectionConfig
}) => {
return `http://localhost:3000/${data.tenantSlug}${
collectionConfig.slug === 'reviews'
? `/review/${data.slug}`
: data.slug !== 'index'
? `/${data.slug}`
: ''
}`;
},Good idea. I've been stuck at this too. I also noticed, in my build anyway, that when the slug is updated, the live preview breaks, as it is still calling the url with original slug, as it is not being updated. This is because i was using the page slug in the live preview url, like I think you have above.
The way I fixed it was to use the page ID in the url instead, similar in the way the Payload website template is
const previewUrl =
${baseUrl}/${data.tenantSlug}/next/preview/page?collection=pages&id=${data.id}&tenant=${data.tenantSlug}that's a good point, and I realized I also had to refine my code to use the id for the preview URL, although for a different reason, as I wanted to have the preview active on a brand new page before it was even published (so, no slug at all).
I also changed my approach to not use a second field for
tenantSlugand instead just get it from the REST API through the tenant's objectID (
data.tenant) - something like that:
livePreview: {
url: async ({ data }) => {
const getTenantData = await fetch(`${process.env.PAYLOAD_URL}/api/tenants/${data.tenant}`).then(res => res.json());
return `${process.env.PAYLOAD_URL}/${getTenantData.slug}/${data.id}?livepreview`;
},
},great stuff 👍
i am having a lot of trouble making live preview work with multi-tenant setup even locally. Can you share the repo code please for a working live preview multi-tenant example?
I tried to make it work, but as i see it the iframe in admin interface and the tenant itself are on different domains and one can not send data to the other due to security restrictions.
I may be doing something wrong or lack understanding of why it is not working as intended, but i only got the preview to work in a separate window and only after i hard refresh this window with F5. Then i see the unpublished changes. But live preview panel itself does not change as a result of field input at all.
maybe this is a known limitaion of multi-tenant setup? I tried to find similar topics here but none are multi-tenant so i decided to ask here. Sorryif this is the wrong place, i just could not find any better
Im interested in solution too
Star
Discord
online
Get dedicated engineering support directly from the Payload team.