import{r as l,p as c,q as u,w as t,z as e,t as s,R as n}from"./vendor.3d5b4206.js";const r={class:"markdown-body"},h=e("h2",{id:"scaffolding-your-directus-extension"},[n("Scaffolding your Directus Extension "),e("a",{class:"header-anchor",href:"#scaffolding-your-directus-extension"},"#")],-1),p=e("p",null,[n("The easiest way to start developing extensions is to use the "),e("code",null,"create-directus-extension"),n(" utility:")],-1),_=e("pre",null,[e("code",{class:"language-bash"},`npm init directus-extension
`)],-1),f=e("p",null,"After specifying the the name of the extension, the type of the extension and the programming language you want to use, the utility will create a folder with the recommended file structure to create an extension.",-1),g=e("h3",{id:"extension-folder-structure"},[n("Extension Folder Structure "),e("a",{class:"header-anchor",href:"#extension-folder-structure"},"#")],-1),y=e("p",null,[n("The folder created by the utility is in fact a npm package. It comes with a few pre-installed packages depending on the extension type and the language you chose. The most important one is "),e("code",null,"@directus/extensions-sdk"),n(". This package includes a CLI, which allows you to build your extension and to scaffold additional extensions, and it provides Typescript helpers and other utilities.")],-1),x=e("p",null,[n("Inside the created folder there is a "),e("code",null,"src/"),n(" folder. This folder contains the entrypoint of your extension. If you write additional source files, they should go into this folder.")],-1),m=e("div",{class:"tip hint"},[e("div",{class:"hint-title"},"Entrypoint"),e("p",null,[n("The entrypoint is either called "),e("code",null,"index.js"),n(" or "),e("code",null,"index.ts"),n(", depending on which programming language you chose.")])],-1),b=e("p",null,[n("The generated "),e("code",null,"package.json"),n(" file contains an additional "),e("code",null,"directus:extension"),n(" field with the following sub-fields:")],-1),w=e("ul",null,[e("li",null,[e("code",null,"type"),n(" \u2014 The type of the extension")]),e("li",null,[e("code",null,"path"),n(" \u2014 The path to the built extension")]),e("li",null,[e("code",null,"source"),n(" \u2014 The path to the source entrypoint")]),e("li",null,[e("code",null,"host"),n(" \u2014 A semver string that indicates with which versions of the Directus host, the extension is compatible with")])],-1),v=e("p",null,"The CLI will use those fields by default to determine the input and output file paths and how the extension should be built.",-1),T=e("h2",{id:"building-your-extension"},[n("Building your Extension "),e("a",{class:"header-anchor",href:"#building-your-extension"},"#")],-1),k=e("p",null,[n("Before your extension can be used by Directus, it has to be built. If you used the "),e("code",null,"create-directus-extension"),n(" utility to scaffold your extension, building your extension is as easy as running:")],-1),I=e("pre",null,[e("code",{class:"language-bash"},`npm run build
`)],-1),j=e("p",null,[n("The generated "),e("code",null,"package.json"),n(" contains a script that calls the "),e("code",null,"directus-extension"),n(" CLI which is part of "),e("code",null,"@directus/extensions-sdk"),n(":")],-1),E=e("pre",null,[e("code",{class:"language-json"},[n(`{
	`),e("span",{class:"hljs-attr"},'"scripts"'),n(`: {
		`),e("span",{class:"hljs-attr"},'"build"'),n(": "),e("span",{class:"hljs-string"},'"directus-extension build"'),n(`
	}
}
`)])],-1),C=e("p",null,[n("If you prefer to scaffold your extension manually, you can use the "),e("code",null,"directus-extension"),n(" CLI binary directly. The "),e("code",null,"--help"),n(" flag provides useful information regarding the available options and flags.")],-1),L=e("p",null,"Internally, the CLI uses Rollup to bundle your extension to a single entrypoint.",-1),D=e("div",{class:"tip hint"},[e("div",{class:"hint-title"},"Watch"),e("p",null,[n("The CLI supports rebuilding extensions whenever a file has changed by using the "),e("code",null,"--watch"),n(" flag.")])],-1),S=e("h3",{id:"configuring-the-cli"},[n("Configuring the CLI "),e("a",{class:"header-anchor",href:"#configuring-the-cli"},"#")],-1),A=e("p",null,[n("Most of the time, it should be sufficient to use the CLI as is. But, in some cases it might be necessary to customize it to your specific needs. This can be done by creating a "),e("code",null,"extension.config.js"),n(" file at the root of your extension package with the following content:")],-1),B=e("pre",null,[e("code",{class:"language-js"},[e("span",{class:"hljs-built_in"},"module"),n(`.exports = {
	`),e("span",{class:"hljs-attr"},"plugins"),n(`: [],
};
`)])],-1),N=e("h4",{id:"supported-options"},[n("Supported Options "),e("a",{class:"header-anchor",href:"#supported-options"},"#")],-1),R=e("ul",null,[e("li",null,[e("code",null,"plugins"),n(" \u2014 An array of Rollup plugins that will be used when building extensions in addition to the built-in ones.")])],-1),M=e("div",{class:"tip hint"},[e("div",{class:"hint-title"},"CommonJS or ESM"),e("p",null,[n("By using the "),e("code",null,"type"),n(" field inside your "),e("code",null,"package.json"),n(" file or using the appropriate file extension ("),e("code",null,".mjs"),n(" or "),e("code",null,".cjs"),n("), the config file can be loaded as a CommonJS or ESM file.")])],-1),O=e("h2",{id:"deploying-your-extension"},[n("Deploying your Extension "),e("a",{class:"header-anchor",href:"#deploying-your-extension"},"#")],-1),W=e("p",null,[n("To deploy your extension, you have to move the output from the "),e("code",null,"dist/"),n(" folder into your project\u2019s "),e("code",null,"./extensions/<extension-folder>/<extension-name>/"),n(" folder. "),e("code",null,"<extension-folder>"),n(" has to be replaced by the extension type in plural form (e.g. interfaces). "),e("code",null,"<extension-name>"),n(" should be replaced with the name of your extension.")],-1),P=e("div",{class:"warning hint"},[e("div",{class:"hint-title"},"Configurable Folders"),e("p",null,"The path to the built extension as well as the extensions directory are configurable and may be located elsewhere.")],-1),V=e("h2",{id:"developing-your-extension"},[n("Developing your Extension "),e("a",{class:"header-anchor",href:"#developing-your-extension"},"#")],-1),z=e("p",null,"To learn more about developing extensions of a specific type, you can refer to one of the individual guides:",-1),F=e("h4",{id:"app-extensions"},[n("App Extensions "),e("a",{class:"header-anchor",href:"#app-extensions"},"#")],-1),J=n("Interfaces"),q=n("Displays"),H=n("Layouts"),U=n("Modules"),X=n("Panels"),G=e("h4",{id:"api-extensions"},[n("API Extensions "),e("a",{class:"header-anchor",href:"#api-extensions"},"#")],-1),K=n("Hooks"),Q=n("Endpoints"),Y={class:"tip hint"},Z=e("div",{class:"hint-title"},"Live Reloading",-1),$=n("When working on extensions, try setting the "),ee=e("code",null,"EXTENSIONS_AUTO_RELOAD",-1),ne=n(" environment variable"),te=n(". This will make the API reload extensions on changes automatically."),ae={setup(oe,{expose:a}){const i={title:"Creating Extensions",modularExtension:!1};return a({frontmatter:i}),(se,ie)=>{const o=l("router-link"),d=l("DocsWrapper");return c(),u(d,{frontmatter:i},{default:t(()=>[e("div",r,[h,p,_,f,g,y,x,m,b,w,v,T,k,I,j,E,C,L,D,S,A,B,N,R,M,O,W,P,V,z,F,e("ul",null,[e("li",null,[s(o,{to:"/docs/extensions/interfaces/"},{default:t(()=>[J]),_:1})]),e("li",null,[s(o,{to:"/docs/extensions/displays/"},{default:t(()=>[q]),_:1})]),e("li",null,[s(o,{to:"/docs/extensions/layouts/"},{default:t(()=>[H]),_:1})]),e("li",null,[s(o,{to:"/docs/extensions/modules/"},{default:t(()=>[U]),_:1})]),e("li",null,[s(o,{to:"/docs/extensions/panels/"},{default:t(()=>[X]),_:1})])]),G,e("ul",null,[e("li",null,[s(o,{to:"/docs/extensions/hooks/"},{default:t(()=>[K]),_:1})]),e("li",null,[s(o,{to:"/docs/extensions/endpoints/"},{default:t(()=>[Q]),_:1})])]),e("div",Y,[Z,e("p",null,[$,s(o,{to:"/docs/configuration/config-options"},{default:t(()=>[ee,ne]),_:1}),te])])])]),_:1})}}};export{ae as default};
