[{"data":1,"prerenderedAt":427},["ShallowReactive",2],{"footer-primary":3,"footer-secondary":93,"footer-description":119,"community-hopline-lightspeed-retail-api":121,"community-hopline-lightspeed-retail-api-next":161,"sales-reps":175},{"items":4},[5,29,49,69],{"id":6,"title":7,"url":8,"page":8,"children":9},"522e608a-77b0-4333-820d-d4f44be2ade1","Solutions",null,[10,15,20,25],{"id":11,"title":12,"url":8,"page":13},"fcafe85a-a798-4710-9e7a-776fe413aae5","Headless CMS",{"permalink":14},"/solutions/headless-cms",{"id":16,"title":17,"url":8,"page":18},"79972923-93cf-4777-9e32-5c9b0315fc10","Backend-as-a-Service",{"permalink":19},"/solutions/backend-as-a-service",{"id":21,"title":22,"url":8,"page":23},"0fa8d0c1-7b64-4f6f-939d-d7fdb99fc407","Product Information",{"permalink":24},"/solutions/product-information-management",{"id":26,"title":27,"url":28,"page":8},"63946d54-6052-4780-8ff4-91f5a9931dcc","100+ Things to Build","https://directus.io/blog/100-tools-apps-and-platforms-you-can-build-with-directus",{"id":30,"title":31,"url":8,"page":8,"children":32},"8ab4f9b1-f3e2-44d6-919b-011d91fe072f","Resources",[33,37,41,45],{"id":34,"title":35,"url":36,"page":8},"f951fb84-8777-4b84-9e91-996fe9d25483","Documentation","https://docs.directus.io",{"id":38,"title":39,"url":40,"page":8},"366febc7-a538-4c08-a326-e6204957f1e3","Guides","https://docs.directus.io/guides/",{"id":42,"title":43,"url":44,"page":8},"aeb9128e-1c5f-417f-863c-2449416433cd","Community","https://directus.chat",{"id":46,"title":47,"url":48,"page":8},"da1c2ed8-0a77-49b0-a903-49c56cb07de5","Release Notes","https://github.com/directus/directus/releases",{"id":50,"title":51,"url":8,"page":8,"children":52},"d61fae8c-7502-494a-822f-19ecff3d0256","Support",[53,57,61,65],{"id":54,"title":55,"url":56,"page":8},"8c43c781-7ebd-475f-a931-747e293c0a88","Issue Tracker","https://github.com/directus/directus/issues",{"id":58,"title":59,"url":60,"page":8},"d77bb78e-cf7b-4e01-932a-514414ba49d3","Feature Requests","https://github.com/directus/directus/discussions?discussions_q=is:open+sort:top",{"id":62,"title":63,"url":64,"page":8},"4346be2b-2c53-476e-b53b-becacec626a6","Community Chat","https://discord.com/channels/725371605378924594/741317677397704757",{"id":66,"title":67,"url":68,"page":8},"26c115d2-49f7-4edc-935e-d37d427fb89d","Cloud Dashboard","https://directus.cloud",{"id":70,"title":71,"url":8,"page":8,"children":72},"49141403-4f20-44ac-8453-25ace1265812","Organization",[73,78,84,88],{"id":74,"title":75,"url":76,"page":77},"1f36ea92-8a5e-47c8-914c-9822a8b9538a","About","/about",{"permalink":76},{"id":79,"title":80,"url":81,"page":82},"b84bf525-5471-4b14-a93c-225f6c386005","Careers","#",{"permalink":83},"/careers",{"id":85,"title":86,"url":87,"page":8},"86aabc3a-433d-434b-9efa-ad1d34be0a34","Brand Assets","https://drive.google.com/drive/folders/1lBOTba4RaA5ikqOn8Ewo4RYzD0XcymG9?usp=sharing",{"id":89,"title":90,"url":8,"page":91},"8d2fa1e3-198e-4405-81e1-2ceb858bc237","Contact",{"permalink":92},"/contact",{"items":94},[95,101,107,113],{"id":96,"title":97,"url":8,"page":98,"children":100},"8a1b7bfa-429d-4ffc-a650-2a5fdcf356da","Cloud Policies",{"permalink":99},"/cloud-policies",[],{"id":102,"title":103,"url":81,"page":104,"children":106},"bea848ef-828f-4306-8017-6b00ec5d4a0c","License",{"permalink":105},"/bsl",[],{"id":108,"title":109,"url":81,"page":110,"children":112},"4e914f47-4bee-42b7-b445-3119ee4196ef","Terms",{"permalink":111},"/terms",[],{"id":114,"title":115,"url":81,"page":116,"children":118},"ea69eda6-d317-4981-8421-fcabb1826bfd","Privacy",{"permalink":117},"/privacy",[],{"description":120},"\u003Cp>A composable backend to build your Headless CMS, BaaS, and more.&nbsp;\u003C/p>",{"id":122,"slug":123,"vimeo_id":124,"description":125,"tile":126,"length":127,"resources":8,"people":8,"episode_number":128,"published":129,"title":130,"video_transcript_html":131,"video_transcript_text":132,"content":8,"status":133,"episode_people":134,"recommendations":149,"season":150,"seo":160},"3090013b-39e2-415b-849c-01dd93c7b831","lightspeed-retail-api","1126261338","Join Bryant as he answers a community question \"I'm integrating Directus with the Lightspeed Retail API [...] has anyone successfully implemented a setup like this?\".","81e3ce98-0159-4ba1-a239-9df8d625d240",14,2,"2025-10-13","Lightspeed Retail API","\u003Cp>Speaker 0: And welcome back to the community hotline. I'm your host Brian Gillespie from Directus. Today, we are answering a question from Directus community member, Daryl Morley. Daryl, how are you, sir? Welcome to the community.\u003C/p>\u003Cp>Happy to have you. I'm gonna answer your question today in detail. Alright. So the question from Daryl. I'm integrating Directus with Lightspeed retail API.\u003C/p>\u003Cp>Not heard Lightspeed name in a long time. That's awesome though. Would like to use, for example, the category ID from Lightspeed as the primary key in my categories collection within Directus. Here's the flow I'm aiming for. One, a the first step.\u003C/p>\u003Cp>A user creates a new category from the Directus admin UI. A before create hook fires that's not actually what it's called in directus, but I got you. It creates a category inside Lightspeed via their API. We receive the category ID back from Lightspeed, and it sets that ID as the primary key of the new Directus record. The issue I'm running into is if the ID field is not auto generated, Directus requires you to provide an ID.\u003C/p>\u003Cp>Yeah. You gotta have that primary key for sure. But I can't know the ID until I call the Lightspeed API inside the hook. Prevents me from using the Lightspeed category ID as a directus primary key. I could potentially store light speed ID in a separate external category ID field, also an option, but then I run into difficulties linking my items to categories as, the directus only sports relationships using the primary key.\u003C/p>\u003Cp>You could establish relationships on that that other field as well, but I totally understand where you're coming from with this. And Daryl's pleading because anyone successfully implemented a setup like this or found a clean workaround, keeps everything in sync. Alright. So we are going to dive into this, Daryl. We are gonna solve this problem together right now.\u003C/p>\u003Cp>Alright. So I've got a blank Directus instance. We're gonna go in and let's create a new collection. I use plurals. We're gonna call it categories.\u003C/p>\u003Cp>Now every collection has to have a primary key. Typically, I just leave this set to ID for simplicity's sake, And usually I go with a generated UUID. We automatically generate that. In this case, where we want that to come from a third party, we are going to use a manually entered string. Now optional fields, I usually add these a 100% of the time.\u003C/p>\u003Cp>Not gonna do that here. I'm just gonna click finish setup, and what we're gonna do is just hit name. Let's add one more field for the name of this category, and this is our categories. Right? So now the challenge is if I go in and this is a new category, just as you said, if I try to save this using command s or just hitting the save button here, requires a value.\u003C/p>\u003Cp>Well, that sucks. That's not what I wanna do. So how do we fix this? There's two ways I can solve this. I'm gonna show you flows first, and then we'll talk about hooks.\u003C/p>\u003Cp>Underneath the hood, they use the same event system. But, one way to do this inside the studio without writing much code or creating a custom extension that you've got to bundle and deploy, you could just do this in a flow. And if the logic is simple enough, it's it's easy to maintain. So we're gonna call this create category is the name of this flow cool in external API. Now I'm not actually gonna use the light speed API here just to keep this high level, but, yeah.\u003C/p>\u003Cp>You'll you'll figure that part of it out. Got faith in you. Got confidence. Alright. So we can trigger these flows a variety of different ways.\u003C/p>\u003Cp>The one we're looking for is event hook, and then we're immediately asked the type of event hook. So there's two, obviously, that's on the screen. There's filter, which is, they said we say blocking here because it blocks that event from actually performing. This is the one that we want because we get a chance to it runs before the item gets saved in the database or before the item gets updated. We'll talk about that in a moment.\u003C/p>\u003Cp>Actions happen after the event is settled, so after the category has been created. In this case, we want to intercept that category as it's being created and before it's saved into the database, and we're gonna alter the payload. So that's what we're doing here. The scope, we just want items create. Right?\u003C/p>\u003Cp>Updated items should already have an ID, and we don't wanna complicate this. The response body is going to be our altered payload with this. So this is the payload that we're gonna save to the database. Now you can choose between all data or the data of the last operation. In this case, I'm just gonna keep this simple and choose data of the last operation to remove as many potential issues.\u003C/p>\u003Cp>Alright. So now we've got our trigger. The next thing that we wanna do is call the external API. Now, I could go in and just choose webhook request URL. I'm gonna hit call external API here.\u003C/p>\u003Cp>This is our step. In this case, it's gonna be a post. And I've just set up, like, a a mock endpoint, from some online free service that when we send this request, it should just send us an ID back. Cool. Alright.\u003C/p>\u003Cp>And now the last step, and, you know, and probably, like, that stuff you're getting back from Lightspeed, you're gonna wanna transform that payload. There's two ways to do that. And let's just call this payload. Right? I could use the run script operation where I've got the full power of JavaScript.\u003C/p>\u003Cp>Now you can't import anything from NPM or use any libraries here, but you you've got, you know, the standard JavaScript library available to you here, and you can run, you know, just basic little functions there. Actually, you don't have the standard JavaScript library. This runs in an isolate, but you got all the basic JavaScript stuff that you're gonna need to transform a payload. The other way to do this is via the transform payload operation, which basically just allows you to adjust what is gonna come out of this thing. And you'll see we're using mustache syntax here for a reason.\u003C/p>\u003Cp>Every operation in a flow appends its data to a key that you can then access. So there's two that are special, which are accountability and dot trigger. That's why they have or I'm sorry. Dollar sign trigger. That's why they have that dollar sign in front of them.\u003C/p>\u003Cp>But the rest of them, we could just do like this. So it'll be call external API. That's the key. And then we're just gonna get the ID. Right?\u003C/p>\u003Cp>Cool. Hit save. This is our flow. Super complicated, super messy. No.\u003C/p>\u003Cp>It's not. It's easy. And then we're gonna go in, and now we're gonna create a new category. So we hit new category, And, oh, undefined. That's not good.\u003C/p>\u003Cp>What is happening here? Call external API. That's my key. Did we get some records back? Okay.\u003C/p>\u003Cp>Yep. So that's the issue. Right? Now I incorrectly formatted this. The thing that we're looking for is dot data dot ID.\u003C/p>\u003Cp>Alright. Always gotta do a bit of troubleshooting. I was hoping I was just gonna one shot that without any AI assistance, but, hey, it happens. And I also saw that we're missing the name. So in this case, you know, I'm just going to call the name.\u003C/p>\u003Cp>So we'll do trigger dot payload dot name. I think that's gonna be correct. Now, again, this is probably where you might wanna use something like JavaScript. But we can see here in our trigger, we have a payload. We have a name for the payload.\u003C/p>\u003Cp>Awesome. Alright. So now, fingers crossed, this should work or it's gonna error out because we can't have two categories with undefined. This is new category. Hit save, And voila, we've got an ID that has come from the ether.\u003C/p>\u003Cp>Now the other approach to do this, you know, if you prefer to express your logic as code and you wanna, you know, check that into Git, what you can do is just build an extension that does the same thing. Right? How do I do that? Well, go to our extension docs. So just go to guides, go to extensions, go to quick start, copy this code.\u003C/p>\u003Cp>I'm just gonna open up my terminal. We are going to put this here, APX direct us extension latest, and we're just gonna write a custom hook. And I'm going to even cheat and just use something that I've got in, another project. Alright. Choose a name for the extension.\u003C/p>\u003Cp>External ID, maybe. Sounds good. Cool. We're gonna use TypeScript auto installer dependencies, and now I've got this external ID extension. It actually needs to be in my extensions folder here inside Directus.\u003C/p>\u003Cp>So, let's just blow this whole thing up and do that. My Directus project CD extensions slash external ID. Why does that not work? CD extensions. What is my directory?\u003C/p>\u003Cp>Oh, somehow I'm inside a Directus. I gotta do that. CD extensions, external ID. Okay. And if I open this up, it's just an index dot ts file whenever the item is created.\u003C/p>\u003Cp>Let's pull up just something from my clipboard. Where are you? Okay. Cool. So this is a pattern that I've used quite a bit before.\u003C/p>\u003Cp>We're just gonna call this categories. Right? And we're gonna erase nano ID. We don't really need that. Cool.\u003C/p>\u003Cp>And we'll say, what, fetch? We could do a fetch call in here. Alright. Constant ID. You know what?\u003C/p>\u003Cp>Let's just let's keep it simple. Nano ID. Cool. So what this does, right, we define this hook, and we'll go into we see this filter that's on items dot create, and then we're passing in the payload, our schema from the direct us. And, we've got our accountability object, which we're not using at all here.\u003C/p>\u003Cp>But then we've got this constant that says, okay. These collections have to have a public ID. And in this case, I could just change it to ID. And all we're doing here is updating the payload and returning the payload. Payload has no ID.\u003C/p>\u003Cp>Alright. I'm gonna hit NPM build. Directus CD extensions. External ID. Cool.\u003C/p>\u003Cp>There we go. PMPM build. Build my extension. I just wanna show you one way that can get this done. And then I've got my directus instance.\u003C/p>\u003Cp>We're gonna need to restart that bad boy. So we'll hit restart. It should pick up that new extension. And fingers crossed. If we go to extensions, we could see that extension.\u003C/p>\u003Cp>And then I can deactivate. Let's not delete it entirely. So we'll just deactivate this flow, change the status to inactive. Cool. Got it.\u003C/p>\u003Cp>And now if I do this again, say test category. Fingers crossed. I know this is not gonna work. Oh, it does work. There we go.\u003C/p>\u003Cp>Test category. I was gonna say, I don't think I have Nano ID in installed, but maybe we're using that somewhere inside Directus itself. Cool. There it is. Couple different ways to achieve it.\u003C/p>\u003Cp>Hope this answers your question. Daryl, my man, thanks for joining the community. Appreciate you. Keep the questions coming. Keep the feedback coming.\u003C/p>\u003Cp>We love it. I'll see you next time on the community hotline.\u003C/p>","And welcome back to the community hotline. I'm your host Brian Gillespie from Directus. Today, we are answering a question from Directus community member, Daryl Morley. Daryl, how are you, sir? Welcome to the community. Happy to have you. I'm gonna answer your question today in detail. Alright. So the question from Daryl. I'm integrating Directus with Lightspeed retail API. Not heard Lightspeed name in a long time. That's awesome though. Would like to use, for example, the category ID from Lightspeed as the primary key in my categories collection within Directus. Here's the flow I'm aiming for. One, a the first step. A user creates a new category from the Directus admin UI. A before create hook fires that's not actually what it's called in directus, but I got you. It creates a category inside Lightspeed via their API. We receive the category ID back from Lightspeed, and it sets that ID as the primary key of the new Directus record. The issue I'm running into is if the ID field is not auto generated, Directus requires you to provide an ID. Yeah. You gotta have that primary key for sure. But I can't know the ID until I call the Lightspeed API inside the hook. Prevents me from using the Lightspeed category ID as a directus primary key. I could potentially store light speed ID in a separate external category ID field, also an option, but then I run into difficulties linking my items to categories as, the directus only sports relationships using the primary key. You could establish relationships on that that other field as well, but I totally understand where you're coming from with this. And Daryl's pleading because anyone successfully implemented a setup like this or found a clean workaround, keeps everything in sync. Alright. So we are going to dive into this, Daryl. We are gonna solve this problem together right now. Alright. So I've got a blank Directus instance. We're gonna go in and let's create a new collection. I use plurals. We're gonna call it categories. Now every collection has to have a primary key. Typically, I just leave this set to ID for simplicity's sake, And usually I go with a generated UUID. We automatically generate that. In this case, where we want that to come from a third party, we are going to use a manually entered string. Now optional fields, I usually add these a 100% of the time. Not gonna do that here. I'm just gonna click finish setup, and what we're gonna do is just hit name. Let's add one more field for the name of this category, and this is our categories. Right? So now the challenge is if I go in and this is a new category, just as you said, if I try to save this using command s or just hitting the save button here, requires a value. Well, that sucks. That's not what I wanna do. So how do we fix this? There's two ways I can solve this. I'm gonna show you flows first, and then we'll talk about hooks. Underneath the hood, they use the same event system. But, one way to do this inside the studio without writing much code or creating a custom extension that you've got to bundle and deploy, you could just do this in a flow. And if the logic is simple enough, it's it's easy to maintain. So we're gonna call this create category is the name of this flow cool in external API. Now I'm not actually gonna use the light speed API here just to keep this high level, but, yeah. You'll you'll figure that part of it out. Got faith in you. Got confidence. Alright. So we can trigger these flows a variety of different ways. The one we're looking for is event hook, and then we're immediately asked the type of event hook. So there's two, obviously, that's on the screen. There's filter, which is, they said we say blocking here because it blocks that event from actually performing. This is the one that we want because we get a chance to it runs before the item gets saved in the database or before the item gets updated. We'll talk about that in a moment. Actions happen after the event is settled, so after the category has been created. In this case, we want to intercept that category as it's being created and before it's saved into the database, and we're gonna alter the payload. So that's what we're doing here. The scope, we just want items create. Right? Updated items should already have an ID, and we don't wanna complicate this. The response body is going to be our altered payload with this. So this is the payload that we're gonna save to the database. Now you can choose between all data or the data of the last operation. In this case, I'm just gonna keep this simple and choose data of the last operation to remove as many potential issues. Alright. So now we've got our trigger. The next thing that we wanna do is call the external API. Now, I could go in and just choose webhook request URL. I'm gonna hit call external API here. This is our step. In this case, it's gonna be a post. And I've just set up, like, a a mock endpoint, from some online free service that when we send this request, it should just send us an ID back. Cool. Alright. And now the last step, and, you know, and probably, like, that stuff you're getting back from Lightspeed, you're gonna wanna transform that payload. There's two ways to do that. And let's just call this payload. Right? I could use the run script operation where I've got the full power of JavaScript. Now you can't import anything from NPM or use any libraries here, but you you've got, you know, the standard JavaScript library available to you here, and you can run, you know, just basic little functions there. Actually, you don't have the standard JavaScript library. This runs in an isolate, but you got all the basic JavaScript stuff that you're gonna need to transform a payload. The other way to do this is via the transform payload operation, which basically just allows you to adjust what is gonna come out of this thing. And you'll see we're using mustache syntax here for a reason. Every operation in a flow appends its data to a key that you can then access. So there's two that are special, which are accountability and dot trigger. That's why they have or I'm sorry. Dollar sign trigger. That's why they have that dollar sign in front of them. But the rest of them, we could just do like this. So it'll be call external API. That's the key. And then we're just gonna get the ID. Right? Cool. Hit save. This is our flow. Super complicated, super messy. No. It's not. It's easy. And then we're gonna go in, and now we're gonna create a new category. So we hit new category, And, oh, undefined. That's not good. What is happening here? Call external API. That's my key. Did we get some records back? Okay. Yep. So that's the issue. Right? Now I incorrectly formatted this. The thing that we're looking for is dot data dot ID. Alright. Always gotta do a bit of troubleshooting. I was hoping I was just gonna one shot that without any AI assistance, but, hey, it happens. And I also saw that we're missing the name. So in this case, you know, I'm just going to call the name. So we'll do trigger dot payload dot name. I think that's gonna be correct. Now, again, this is probably where you might wanna use something like JavaScript. But we can see here in our trigger, we have a payload. We have a name for the payload. Awesome. Alright. So now, fingers crossed, this should work or it's gonna error out because we can't have two categories with undefined. This is new category. Hit save, And voila, we've got an ID that has come from the ether. Now the other approach to do this, you know, if you prefer to express your logic as code and you wanna, you know, check that into Git, what you can do is just build an extension that does the same thing. Right? How do I do that? Well, go to our extension docs. So just go to guides, go to extensions, go to quick start, copy this code. I'm just gonna open up my terminal. We are going to put this here, APX direct us extension latest, and we're just gonna write a custom hook. And I'm going to even cheat and just use something that I've got in, another project. Alright. Choose a name for the extension. External ID, maybe. Sounds good. Cool. We're gonna use TypeScript auto installer dependencies, and now I've got this external ID extension. It actually needs to be in my extensions folder here inside Directus. So, let's just blow this whole thing up and do that. My Directus project CD extensions slash external ID. Why does that not work? CD extensions. What is my directory? Oh, somehow I'm inside a Directus. I gotta do that. CD extensions, external ID. Okay. And if I open this up, it's just an index dot ts file whenever the item is created. Let's pull up just something from my clipboard. Where are you? Okay. Cool. So this is a pattern that I've used quite a bit before. We're just gonna call this categories. Right? And we're gonna erase nano ID. We don't really need that. Cool. And we'll say, what, fetch? We could do a fetch call in here. Alright. Constant ID. You know what? Let's just let's keep it simple. Nano ID. Cool. So what this does, right, we define this hook, and we'll go into we see this filter that's on items dot create, and then we're passing in the payload, our schema from the direct us. And, we've got our accountability object, which we're not using at all here. But then we've got this constant that says, okay. These collections have to have a public ID. And in this case, I could just change it to ID. And all we're doing here is updating the payload and returning the payload. Payload has no ID. Alright. I'm gonna hit NPM build. Directus CD extensions. External ID. Cool. There we go. PMPM build. Build my extension. I just wanna show you one way that can get this done. And then I've got my directus instance. We're gonna need to restart that bad boy. So we'll hit restart. It should pick up that new extension. And fingers crossed. If we go to extensions, we could see that extension. And then I can deactivate. Let's not delete it entirely. So we'll just deactivate this flow, change the status to inactive. Cool. Got it. And now if I do this again, say test category. Fingers crossed. I know this is not gonna work. Oh, it does work. There we go. Test category. I was gonna say, I don't think I have Nano ID in installed, but maybe we're using that somewhere inside Directus itself. Cool. There it is. Couple different ways to achieve it. Hope this answers your question. Daryl, my man, thanks for joining the community. Appreciate you. Keep the questions coming. Keep the feedback coming. We love it. I'll see you next time on the community hotline.","published",[135],{"people_id":136},{"id":137,"first_name":138,"last_name":139,"avatar":140,"bio":141,"links":142},"791e1503-1d88-463d-9347-0b9192933576","Bryant","Gillespie","9013afc8-e8d7-4182-9b18-44db08117bb9","Developer Advocate at Directus",[143,146],{"url":144,"service":145},"https://directus.io/team/bryant-gillespie","website",{"service":147,"url":148},"github","https://github.com/bryantgillespie",[],{"id":151,"number":152,"year":153,"episodes":154,"show":157},"8e34d235-6112-474d-8ae9-5506e9322a93",1,"2025",[155,122,156],"77fddac4-c3c3-4752-9ce7-ad0d149f5896","dc17b7f3-af98-40a4-b205-4cda6af48c71",{"title":158,"tile":159},"The Directus Community Hopline","548ab4bb-5825-4b21-921f-176b0890664e",{"title":8,"meta_description":8},{"id":156,"slug":162,"season":151,"vimeo_id":163,"description":164,"tile":165,"length":166,"resources":8,"people":8,"episode_number":167,"published":129,"title":168,"video_transcript_html":169,"video_transcript_text":170,"content":8,"seo":171,"status":133,"episode_people":172,"recommendations":174},"building-fronted-cms-within-directus","1126261892","Join Bryant as he answers a community question \"Is building frontend CMS within Directus possible?\".","a4ebec91-f105-41a5-b68d-46e76eb58354",6,3,"Building Frontend CMS within Directus","\u003Cp>Speaker 0: And we're back with another episode of the community hotline. Welcome. Today, we have Wylus, Wylies. Sorry if I get the name wrong. Welcome to the community.\u003C/p>\u003Cp>Glad to have you, friend. Alright. So our question today, is building a front end CMS within direct as possible? So we'll tackle that in a moment. Let's read the rest of this.\u003C/p>\u003Cp>Good day, gurus. I'm looking for a powerful tool to support the following. SaaS, hosting multiple tenant within one project, creating pages if possible, but how could I render it within Directus? I saw tutorials, but only using Directus as a back end. How can we make this work potentially?\u003C/p>\u003Cp>Alright. So first and foremost, right, Directus is set up to be a headless CMS and back end. So that paradigm is very important to understand. WordPress is, has a headless option, but it's ideally a monolithic kind of solution where you've got your CMS, and you've got your front end, and the templating, and all that is mixed together. Whereas, Directus is headless and that's the way it's designed.\u003C/p>\u003Cp>So you can, send that data to multiple sources. Maybe you've got a a front end, maybe you've got a mobile application, maybe you've got a kiosk or a display that you need to send data to or fetch data, from a back end. Directus is great for that. When it comes to building a front end CMS within Directus, basically, you're talking about the Directus App Studio. Right?\u003C/p>\u003Cp>I can not only just add my own team members to this, but I could potentially create a multi tenant CMS out of the data studio itself. So, if you take a look at our CMS starter, this is available, you know, through the website. If you go to directives.io, you hit this command line, or the script here. Just pop this into your terminal, select the CMS option, or if you go to our cloud, log in, you spin up a new project inside cloud, just pick the CMS template and you can get access to what I'm gonna show you here today. Right?\u003C/p>\u003Cp>So this comes out of the box. This is a a CMS. It's exactly what you would expect out of a CMS. We have pages, we have posts, etcetera. Now if I wanted to make this multi tenant, how would I go about it?\u003C/p>\u003Cp>Well, first, I would create a tenant collection. Maybe that's sites or, properties or whatever we wanna call it. And then for each collection within this, I add a relationship, many to one, back to that site's collection, back to that tenant collection. And then within our access policies, you've got everything you need to basically scope access down. So you can filter based on the site, so that one tenant cannot read the, data from another.\u003C/p>\u003Cp>Now, there's an specific episode of 100 apps, one hundred hours where we cover this exact thing. So just look for multi site. That mission is season three episode two. You can follow right along with this and see how to set up a multi tenant CMS using Directus. Now to your other question.\u003C/p>\u003Cp>Right? How can I create pages or render within Directus? Now Directus itself is extremely flexible, and this is where our extensions come into play. And a good example of that, if we just go to directus.io and we look at our sandbox demo, there's a little extra module in here that is not, baked into directus core. This is just an extension that we built to give you a welcome page that does get rendered inside Directus.\u003C/p>\u003Cp>Now this is coming from a separate Directus instance, but again, all of Directus is modular and extensible. So this is actually a module extension. But if we just go to our docs, we look for our guides, we go to the extensions section, You can learn all about extensions. So you can customize the way that you interact with data inside the forms. Those are interfaces.\u003C/p>\u003Cp>You can control the way that data is displayed in the different layouts throughout the studio. That is a display. You have layouts themselves, so you can control the listing of these items. You know, they think tables or kanban, views or maps, whatever. We can add panels to the dashboards and kind of the overall level where you've got total control over what gets rendered on the page, you have a module.\u003C/p>\u003Cp>So if you want flexibility on how things are rendered inside Directus, Maybe you wanna add some extra pages to it or you just want something, a blank canvas where you could totally experiment with whatever you want. Custom modules are what you're looking at. So, with that in mind, I hope that is enough to answer your question. Wireless. Wireless.\u003C/p>\u003Cp>Sorry. Again, I hate if I get it wrong. But that's it for this episode of Community Hopeline. If you want me to answer one of your questions on the next change log or or on the next community hop line, make sure you hop into the Directus community, community.directus.io, and I'll see you around.\u003C/p>","And we're back with another episode of the community hotline. Welcome. Today, we have Wylus, Wylies. Sorry if I get the name wrong. Welcome to the community. Glad to have you, friend. Alright. So our question today, is building a front end CMS within direct as possible? So we'll tackle that in a moment. Let's read the rest of this. Good day, gurus. I'm looking for a powerful tool to support the following. SaaS, hosting multiple tenant within one project, creating pages if possible, but how could I render it within Directus? I saw tutorials, but only using Directus as a back end. How can we make this work potentially? Alright. So first and foremost, right, Directus is set up to be a headless CMS and back end. So that paradigm is very important to understand. WordPress is, has a headless option, but it's ideally a monolithic kind of solution where you've got your CMS, and you've got your front end, and the templating, and all that is mixed together. Whereas, Directus is headless and that's the way it's designed. So you can, send that data to multiple sources. Maybe you've got a a front end, maybe you've got a mobile application, maybe you've got a kiosk or a display that you need to send data to or fetch data, from a back end. Directus is great for that. When it comes to building a front end CMS within Directus, basically, you're talking about the Directus App Studio. Right? I can not only just add my own team members to this, but I could potentially create a multi tenant CMS out of the data studio itself. So, if you take a look at our CMS starter, this is available, you know, through the website. If you go to directives.io, you hit this command line, or the script here. Just pop this into your terminal, select the CMS option, or if you go to our cloud, log in, you spin up a new project inside cloud, just pick the CMS template and you can get access to what I'm gonna show you here today. Right? So this comes out of the box. This is a a CMS. It's exactly what you would expect out of a CMS. We have pages, we have posts, etcetera. Now if I wanted to make this multi tenant, how would I go about it? Well, first, I would create a tenant collection. Maybe that's sites or, properties or whatever we wanna call it. And then for each collection within this, I add a relationship, many to one, back to that site's collection, back to that tenant collection. And then within our access policies, you've got everything you need to basically scope access down. So you can filter based on the site, so that one tenant cannot read the, data from another. Now, there's an specific episode of 100 apps, one hundred hours where we cover this exact thing. So just look for multi site. That mission is season three episode two. You can follow right along with this and see how to set up a multi tenant CMS using Directus. Now to your other question. Right? How can I create pages or render within Directus? Now Directus itself is extremely flexible, and this is where our extensions come into play. And a good example of that, if we just go to directus.io and we look at our sandbox demo, there's a little extra module in here that is not, baked into directus core. This is just an extension that we built to give you a welcome page that does get rendered inside Directus. Now this is coming from a separate Directus instance, but again, all of Directus is modular and extensible. So this is actually a module extension. But if we just go to our docs, we look for our guides, we go to the extensions section, You can learn all about extensions. So you can customize the way that you interact with data inside the forms. Those are interfaces. You can control the way that data is displayed in the different layouts throughout the studio. That is a display. You have layouts themselves, so you can control the listing of these items. You know, they think tables or kanban, views or maps, whatever. We can add panels to the dashboards and kind of the overall level where you've got total control over what gets rendered on the page, you have a module. So if you want flexibility on how things are rendered inside Directus, Maybe you wanna add some extra pages to it or you just want something, a blank canvas where you could totally experiment with whatever you want. Custom modules are what you're looking at. So, with that in mind, I hope that is enough to answer your question. Wireless. Wireless. Sorry. Again, I hate if I get it wrong. But that's it for this episode of Community Hopeline. If you want me to answer one of your questions on the next change log or or on the next community hop line, make sure you hop into the Directus community, community.directus.io, and I'll see you around.","5d2ee344-765f-4c79-ba18-539cb6470e5f",[173],"4ddd0967-d465-42f9-8093-dc2f01a5f3c5",[],{"reps":176},[177,233],{"name":178,"sdr":8,"link":179,"countries":180,"states":182},"John Daniels","https://meet.directus.io/meetings/john2144/john-contact-form-meeting",[181],"United States",[183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232],"Michigan","Indiana","Ohio","West Virginia","Kentucky","Virginia","Tennessee","North Carolina","South Carolina","Georgia","Florida","Alabama","Mississippi","New York","MI","IN","OH","WV","KY","VA","TN","NC","SC","GA","FL","AL","MS","NY","Connecticut","CT","Delaware","DE","Maine","ME","Maryland","MD","Massachusetts","MA","New Hampshire","NH","New Jersey","NJ","Pennsylvania","PA","Rhode Island","RI","Vermont","VT","Washington DC","DC",{"name":234,"link":235,"countries":236},"Michelle Riber","https://meetings.hubspot.com/mriber",[237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,214,425,426],"Albania","ALB","Algeria","DZA","Andorra","AND","Angola","AGO","Austria","AUT","Belgium","BEL","Benin","BEN","Bosnia and Herzegovina","BIH","Botswana","BWA","Bulgaria","BGR","Burkina Faso","BFA","Burundi","BDI","Cameroon","CMR","Cape Verde","CPV","Central African Republic","CAF","Chad","TCD","Comoros","COM","Côte d'Ivoire","CIV","Croatia","HRV","Czech Republic","CZE","Democratic Republic of Congo","COD","Denmark","DNK","Djibouti","DJI","Egypt","EGY","Equatorial Guinea","GNQ","Eritrea","ERI","Estonia","EST","Eswatini","SWZ","Ethiopia","ETH","Finland","FIN","France","FRA","Gabon","GAB","Gambia","GMB","Ghana","GHA","Greece","GRC","Guinea","GIN","Guinea-Bissau","GNB","Hungary","HUN","Iceland","ISL","Ireland","IRL","Italy","ITA","Kenya","KEN","Latvia","LVA","Lesotho","LSO","Liberia","LBR","Libya","LBY","Liechtenstein","LIE","Lithuania","LTU","Luxembourg","LUX","Madagascar","MDG","Malawi","MWI","Mali","MLI","Malta","MLT","Mauritania","MRT","Mauritius","MUS","Moldova","MDA","Monaco","MCO","Montenegro","MNE","Morocco","MAR","Mozambique","MOZ","Namibia","NAM","Niger","NER","Nigeria","NGA","North Macedonia","MKD","Norway","NOR","Poland","POL","Portugal","PRT","Republic of Congo","COG","Romania","ROU","Rwanda","RWA","San Marino","SMR","São Tomé and Príncipe","STP","Senegal","SEN","Serbia","SRB","Seychelles","SYC","Sierra Leone","SLE","Slovakia","SVK","Slovenia","SVN","Somalia","SOM","South Africa","ZAF","South Sudan","SSD","Spain","ESP","Sudan","SDN","Sweden","SWE","Tanzania","TZA","Togo","TGO","Tunisia","TUN","Uganda","UGA","United Kingdom","GBR","Vatican City","VAT","Zambia","ZMB","Zimbabwe","ZWE","UK","Germany","Netherlands","Switzerland","CH","NL",1773850428194]