[{"data":1,"prerenderedAt":9061},["ShallowReactive",2],{"content-navigation":3,"$fY4mAj2l3kRkTDttxn6FGzqBc2O9HAJ2qp-_8LmMX7aw":1825,"/tutorials/getting-started/using-authentication-in-sveltekit":1830},[4,112,119,224,333,429,481,1087,1113,1142],{"title":5,"path":6,"stem":7,"children":8,"page":89},"Partials","/_partials","_partials",[9,15,20,25,29,33,38,42,47,51,56,60,64,68,90,94,98,103,108],{"title":10,"path":11,"stem":12,"description":13,"icon":14,"links":14},"Advanced Field Creation Mode","/_partials/advanced-field-creation-mode","_partials/advanced-field-creation-mode","You can use these advanced options to automatically set the values of fields at specific events by clicking on \"Continue in Advanced Field Creation Mode\".",null,{"title":16,"path":17,"stem":18,"description":19,"icon":14,"links":14},"Authentication","/_partials/authentication","_partials/authentication","While the Public role can be configured to make data available without authentication, anything that is not public requires a user to authenticate their requests.",{"title":21,"path":22,"stem":23,"description":24,"icon":14,"links":14},"Config Env Vars","/_partials/config-env-vars","_partials/config-env-vars","",{"title":26,"path":27,"stem":28,"description":24,"icon":14,"links":14},"Deployment Public Instance","/_partials/deployment-public-instance","_partials/deployment-public-instance",{"title":30,"path":31,"stem":32,"description":24,"icon":14,"links":14},"Engine Studio Box","/_partials/engine-studio-box","_partials/engine-studio-box",{"title":34,"path":35,"stem":36,"description":37,"icon":14,"links":14},"Extension Hook Footguns","/_partials/extension-hook-footguns","_partials/extension-hook-footguns","Directus reads system collections to operate. Be careful when modifying the output of system collection read or query events. Also ensure not to directly or indirectly emit the same event your hook is handling or you will create an infinite loop.",{"title":39,"path":40,"stem":41,"description":24,"icon":14,"links":14},"Extension Hook System Collections","/_partials/extension-hook-system-collections","_partials/extension-hook-system-collections",{"title":43,"path":44,"stem":45,"description":46,"icon":14,"links":14},"Extensions Api","/_partials/extensions-api","_partials/extensions-api","This extension type is loaded into the Directus process. They can use the provided services exported by the @directus/extensions-sdk package and can be written in JavaScript or TypeScript.",{"title":48,"path":49,"stem":50,"description":24,"icon":14,"links":14},"Extensions Api Internals","/_partials/extensions-api-internals","_partials/extensions-api-internals",{"title":52,"path":53,"stem":54,"description":55,"icon":14,"links":14},"Extensions App","/_partials/extensions-app","_partials/extensions-app","This extension type is loaded into the Directus Data Studio. They are are built with Vue 3, and can use the provided composables exported by the @directus/extensions-sdk package. Extensions can be written in JavaScript or TypeScript.",{"title":57,"path":58,"stem":59,"description":24,"icon":14,"links":14},"Extensions App Internals","/_partials/extensions-app-internals","_partials/extensions-app-internals",{"title":61,"path":62,"stem":63,"description":24,"icon":14,"links":14},"Extensions Theme","/_partials/extensions-theme","_partials/extensions-theme",{"title":65,"path":66,"stem":67,"description":24,"icon":14,"links":14},"Extensions Uid","/_partials/extensions-uid","_partials/extensions-uid",{"title":69,"path":70,"stem":71,"children":72,"page":89},"Home Hero","/_partials/home-hero","_partials/home-hero",[73,77,81,85],{"title":74,"path":75,"stem":76,"description":24,"icon":14,"links":14},"Auth","/_partials/home-hero/auth","_partials/home-hero/auth",{"title":78,"path":79,"stem":80,"description":24,"icon":14,"links":14},"Data","/_partials/home-hero/data","_partials/home-hero/data",{"title":82,"path":83,"stem":84,"description":24,"icon":14,"links":14},"File","/_partials/home-hero/file","_partials/home-hero/file",{"title":86,"path":87,"stem":88,"description":24,"icon":14,"links":14},"Realtime","/_partials/home-hero/realtime","_partials/home-hero/realtime",false,{"title":91,"path":92,"stem":93,"description":24,"icon":14,"links":14},"Json Function","/_partials/json-function","_partials/json-function",{"title":95,"path":96,"stem":97,"description":24,"icon":14,"links":14},"License","/_partials/license","_partials/license",{"title":99,"path":100,"stem":101,"description":102,"icon":14,"links":14},"Query Functions","/_partials/query-functions","_partials/query-functions","Functions accept a field and return a modified value. Functions can be used in any query parameter you'd normally supply a field key, including fields, aggregation, and filters.",{"title":104,"path":105,"stem":106,"description":107,"icon":14,"links":14},"Quickstart Making Calls","/_partials/quickstart-making-calls","_partials/quickstart-making-calls","You can use a visual API testing tool like Postman or Hoppscotch, a terminal-based based tool like curl or HTTPie, or make HTTP requests directly in a script written in your programming language of choice.",{"title":109,"path":110,"stem":111,"description":24,"icon":14,"links":14},"Snippet Auth Token","/_partials/snippet-auth-token","_partials/snippet-auth-token",{"title":113,"path":114,"stem":115,"children":116,"description":118,"icon":14,"links":14},"Directus API Reference","/api","api/index",[117],{"title":113,"path":114,"stem":115,"description":118,"icon":14,"links":14},"Learn how to use our API",{"title":120,"path":121,"stem":122,"children":123,"page":89},"Cloud","/cloud","cloud",[124,144,174,204],{"title":125,"path":126,"stem":127,"children":128,"page":89},"Getting Started","/cloud/getting-started","cloud/1.getting-started",[129,134,139],{"title":130,"path":131,"stem":132,"description":133,"icon":14,"links":14},"Introduction","/cloud/getting-started/introduction","cloud/1.getting-started/1.introduction","Whether you're a hobbyist, startup, or enterprise, our flexible Directus Cloud platform lets you get up and running with Directus quickly.",{"title":135,"path":136,"stem":137,"description":138,"icon":14,"links":14},"Cloud Teams","/cloud/getting-started/teams","cloud/1.getting-started/2.teams","A team is an organizational system that groups accounts together as team members and provides consolidated billing for projects.",{"title":140,"path":141,"stem":142,"description":143,"icon":14,"links":14},"Managing Cloud Accounts","/cloud/getting-started/accounts","cloud/1.getting-started/3.accounts","An account is your portal to Directus Cloud. You can use it to manage your teams, team members, projects and billing.",{"title":145,"path":146,"stem":147,"children":148,"page":89},"Projects","/cloud/projects","cloud/2.projects",[149,154,159,164,169],{"title":150,"path":151,"stem":152,"description":153,"icon":14,"links":14},"Create a Project","/cloud/projects/create","cloud/2.projects/1.create","Create a project in Directus Cloud.",{"title":155,"path":156,"stem":157,"description":158,"icon":14,"links":14},"Destroy a Project","/cloud/projects/destroy","cloud/2.projects/2.destroy","Destroy a Directus Cloud project and cancel your subscription.",{"title":160,"path":161,"stem":162,"description":163,"icon":14,"links":14},"Version Upgrades","/cloud/projects/version-upgrades","cloud/2.projects/3.version-upgrades","Learn about automatic upgrades and version locking in Directus Cloud.",{"title":165,"path":166,"stem":167,"description":168,"icon":14,"links":14},"Monitoring Projects","/cloud/projects/monitoring","cloud/2.projects/4.monitoring","Learn how to monitor your Directus Cloud project.",{"title":170,"path":171,"stem":172,"description":173,"icon":14,"links":14},"Backups","/cloud/projects/backups","cloud/2.projects/5.backups","Learn about automatic backups in Directus Cloud.",{"title":175,"path":176,"stem":177,"children":178,"page":89},"Configuration","/cloud/configuration","cloud/3.configuration",[179,184,189,194,199],{"title":180,"path":181,"stem":182,"description":183,"icon":14,"links":14},"Custom Domains","/cloud/configuration/custom-domains","cloud/3.configuration/1.custom-domains","Learn how to set up a custom domain for your Directus Enterprise Cloud project.",{"title":185,"path":186,"stem":187,"description":188,"icon":14,"links":14},"Environment Variables","/cloud/configuration/environment-variables","cloud/3.configuration/2.environment-variables","Learn about environment variables in Directus Cloud.",{"title":190,"path":191,"stem":192,"description":193,"icon":14,"links":14},"Direct Database Access","/cloud/configuration/direct-database-access","cloud/3.configuration/3.direct-database-access","Learn how to directly access your Directus Cloud project's database.",{"title":195,"path":196,"stem":197,"description":198,"icon":14,"links":14},"Custom Extensions","/cloud/configuration/custom-extensions","cloud/3.configuration/4.custom-extensions","Learn how to deploy custom extensions to your Directus Cloud project.",{"title":200,"path":201,"stem":202,"description":203,"icon":14,"links":14},"Datacenter Regions","/cloud/configuration/datacenter-regions","cloud/3.configuration/5.datacenter-regions","Learn where datacenters for cloud projects are located.",{"title":205,"path":206,"stem":207,"children":208,"page":89},"Billing","/cloud/billing","cloud/4.billing",[209,214,219],{"title":210,"path":211,"stem":212,"description":213,"icon":14,"links":14},"Manage Billing","/cloud/billing/manage-billing","cloud/4.billing/1.manage-billing","Learn how to manage billing for your Directus Cloud project.",{"title":215,"path":216,"stem":217,"description":218,"icon":14,"links":14},"Changing Your Tier","/cloud/billing/changing-tier","cloud/4.billing/2.changing-tier","Learn how to change the tier of your Directus Cloud project.",{"title":220,"path":221,"stem":222,"description":223,"icon":14,"links":14},"Cancel Your Subscription","/cloud/billing/cancel-subscription","cloud/4.billing/3.cancel-subscription","Learn how to cancel your Directus Cloud project subscription.",{"title":225,"path":226,"stem":227,"children":228,"page":89},"Community","/community","community",[229,249,274,293,318],{"title":230,"path":231,"stem":232,"children":233,"page":89},"Overview","/community/overview","community/1.overview",[234,239,244],{"title":235,"path":236,"stem":237,"description":238,"icon":14,"links":14},"Welcome","/community/overview/welcome","community/1.overview/1.welcome","Welcome to the Directus community!",{"title":240,"path":241,"stem":242,"description":243,"icon":14,"links":14},"Code of Conduct","/community/overview/conduct","community/1.overview/2.conduct","Our standards, responsibilities, and enforcement guidelines to create a positive community.",{"title":245,"path":246,"stem":247,"description":248,"icon":14,"links":14},"Moderation Guidelines","/community/overview/moderation","community/1.overview/3.moderation","Guidelines we give to community moderators.",{"title":250,"path":251,"stem":252,"children":253,"page":89},"Contribution","/community/contribution","community/2.contribution",[254,259,264,269],{"title":255,"path":256,"stem":257,"description":258,"icon":14,"links":14},"Translations","/community/contribution/translations","community/2.contribution/1.translations","How to contribute to translating the Data Studio.",{"title":260,"path":261,"stem":262,"description":263,"icon":14,"links":14},"Documentation","/community/contribution/documentation","community/2.contribution/2.documentation","How to contribute to the Directus documentation.",{"title":265,"path":266,"stem":267,"description":268,"icon":14,"links":14},"Feature Requests","/community/contribution/feature-requests","community/2.contribution/3.feature-requests","How to add feature requests, and our process for reviewing them.",{"title":270,"path":271,"stem":272,"description":273,"icon":14,"links":14},"Pull Requests","/community/contribution/pull-requests","community/2.contribution/4.pull-requests","Our process for contributing pull requests to Directus.",{"title":275,"path":276,"stem":277,"children":278,"page":89},"Codebase","/community/codebase","community/3.codebase",[279,283,288],{"title":275,"path":280,"stem":281,"description":282,"icon":14,"links":14},"/community/codebase/overview","community/3.codebase/1.overview","Overview of the Directus codebase for new contributors",{"title":284,"path":285,"stem":286,"description":287,"icon":14,"links":14},"Development Environment","/community/codebase/dev-environment","community/3.codebase/2.dev-environment","How to set up and run a development environment for Directus so that you can work on the platform's source code.",{"title":289,"path":290,"stem":291,"description":292,"icon":14,"links":14},"Testing","/community/codebase/testing","community/3.codebase/3.testing","How to run unit and blackbox tests in the Directus codebase.",{"title":294,"path":295,"stem":296,"children":297,"page":89},"Reporting And Support","/community/reporting-and-support","community/4.reporting-and-support",[298,303,308,313],{"title":299,"path":300,"stem":301,"description":302,"icon":14,"links":14},"Troubleshooting Steps","/community/reporting-and-support/troubleshooting-steps","community/4.reporting-and-support/1.troubleshooting-steps","If you're experiencing issues or think you have found a problem in Directus, be sure to follow these steps.",{"title":304,"path":305,"stem":306,"description":307,"icon":14,"links":14},"Bug Reporting","/community/reporting-and-support/bug-reporting","community/4.reporting-and-support/2.bug-reporting","How to report bugs in Directus.",{"title":309,"path":310,"stem":311,"description":312,"icon":14,"links":14},"Security Reporting","/community/reporting-and-support/security-reporting","community/4.reporting-and-support/3.security-reporting","How to report security issues in Directus.",{"title":314,"path":315,"stem":316,"description":317,"icon":14,"links":14},"Customer Support","/community/reporting-and-support/customer-support","community/4.reporting-and-support/4.customer-support","How to get help with Directus as a user and customer.",{"title":319,"path":320,"stem":321,"children":322,"page":89},"Programs","/community/programs","community/5.programs",[323,328],{"title":324,"path":325,"stem":326,"description":327,"icon":14,"links":14},"Guest Authors","/community/programs/guest-authors","community/5.programs/1.guest-authors","Our guest author program invites authors to join and get paid to write tutorials for the Directus community.",{"title":329,"path":330,"stem":331,"description":332,"icon":14,"links":14},"Directus Labs","/community/programs/directus-labs","community/5.programs/2.directus-labs","Directus Labs is the official organization for Directus templates, settings and experimental projects.",{"title":175,"path":334,"stem":335,"children":336,"page":89},"/configuration","configuration",[337,341,346,351,356,361,366,371,376,381,386,391,396,401,406,410,415,420,425],{"title":130,"path":338,"stem":339,"description":340,"icon":14,"links":14},"/configuration/intro","configuration/0.intro","Environment variables are used for all configuration within a Directus project. These variables can be defined in a number of ways, which we cover below.",{"title":342,"path":343,"stem":344,"description":345,"icon":14,"links":14},"General","/configuration/general","configuration/1.general","Configuration for the general system, server, first admin user, and telemetry.",{"title":347,"path":348,"stem":349,"description":350,"icon":14,"links":14},"AI","/configuration/ai","configuration/ai","Configuration for AI Assistant and Model Context Protocol (MCP) features.",{"title":352,"path":353,"stem":354,"description":355,"icon":14,"links":14},"Auth & SSO","/configuration/auth-sso","configuration/auth-sso","Configuration for authentication methods, including local email/password, OAuth 2.0, OpenID, LDAP, and SAML.",{"title":357,"path":358,"stem":359,"description":360,"icon":14,"links":14},"Cache","/configuration/cache","configuration/cache","Configuration for internal and output caching.",{"title":362,"path":363,"stem":364,"description":365,"icon":14,"links":14},"Database","/configuration/database","configuration/database","Configuration for database connections.",{"title":367,"path":368,"stem":369,"description":370,"icon":14,"links":14},"Email","/configuration/email","configuration/email","Configuration for email settings and templates.",{"title":372,"path":373,"stem":374,"description":375,"icon":14,"links":14},"Extensions","/configuration/extensions","configuration/extensions","Configuration for extensions and the Directus Marketplace.",{"title":377,"path":378,"stem":379,"description":380,"icon":14,"links":14},"Files","/configuration/files","configuration/files","Configuration for storage locations, metadata, upload limits, and transformations.",{"title":382,"path":383,"stem":384,"description":385,"icon":14,"links":14},"Flows","/configuration/flows","configuration/flows","Configure environment variables, memory, and timeout for Flows.",{"title":387,"path":388,"stem":389,"description":390,"icon":14,"links":14},"Logging","/configuration/logging","configuration/logging","Configuration for general and Realtime logging.",{"title":392,"path":393,"stem":394,"description":395,"icon":14,"links":14},"Metrics","/configuration/metrics","configuration/metrics","Configuration for metrics.",{"title":397,"path":398,"stem":399,"description":400,"icon":14,"links":14},"Migrations","/configuration/migrations","configuration/migrations","Creation of custom migration files to automate database changes.",{"title":402,"path":403,"stem":404,"description":405,"icon":14,"links":14},"PM2","/configuration/pm2","configuration/pm2","Configuration for PM2, the process manager for Directus.",{"title":86,"path":407,"stem":408,"description":409,"icon":14,"links":14},"/configuration/realtime","configuration/realtime","Configuration for WebSockets and GraphQL Subscriptions.",{"title":411,"path":412,"stem":413,"description":414,"icon":14,"links":14},"Security & Limits","/configuration/security-limits","configuration/security-limits","Configuration for access tokens, cookies, CSP, hashing, CORS, rate limiting, and request limits.",{"title":416,"path":417,"stem":418,"description":419,"icon":14,"links":14},"Synchronization","/configuration/synchronization","configuration/synchronization","Configuration around synchronization and Redis.",{"title":421,"path":422,"stem":423,"description":424,"icon":14,"links":14},"Theming","/configuration/theming","configuration/theming","Configuration of the Data Studio's theming engine and appearance settings.",{"title":255,"path":426,"stem":427,"description":428,"icon":14,"links":14},"/configuration/translations","configuration/translations","Directus supports translations for both the Data Studio UI and authored content.",{"title":125,"description":14,"icon":14,"links":14,"path":430,"stem":431,"children":432,"page":89},"/getting-started","getting-started",[433,437,442,446,451,456,461,466,471,476],{"title":230,"path":434,"stem":435,"description":436,"icon":14,"links":14},"/getting-started/overview","getting-started/1.overview","Learn about the Directus Data Engine and Studio, when to use it, and a how it works.",{"title":438,"path":439,"stem":440,"description":441,"icon":14,"links":14},"Accessibility","/getting-started/accessibility","getting-started/10.accessibility","We are always looking for ways to make Directus Studio more accessible. Here are some of the methods we currently support.",{"title":150,"path":443,"stem":444,"description":445,"icon":14,"links":14},"/getting-started/create-a-project","getting-started/2.create-a-project","Learn about how to create a managed Directus project or self-host with Docker.",{"title":447,"path":448,"stem":449,"description":450,"icon":14,"links":14,"label":447},"Configure a Data Model","/getting-started/data-model","getting-started/3.data-model","This guide will cover creating a collection in Directus via the Data Studio, creating fields, and configuring relationships.",{"title":452,"path":453,"stem":454,"description":455,"icon":14,"links":14},"Use the API","/getting-started/use-the-api","getting-started/4.use-the-api","Get started with Directus APIs. Learn to interact with collections, fetch, and create data.",{"title":457,"path":458,"stem":459,"description":460,"icon":14,"links":14},"Authenticate a User","/getting-started/authenticate-user","getting-started/5.authenticate-user","Get started with Directus Auth. Learn how to register, login, create users, and make authenticated requests.",{"title":462,"path":463,"stem":464,"description":465,"icon":14,"links":14},"Upload & Access Files","/getting-started/upload-files","getting-started/6.upload-files","This guide will cover importing a file via URL, requesting assets, and using transformation parameters.",{"title":467,"path":468,"stem":469,"description":470,"icon":14,"links":14},"Create an Automation","/getting-started/create-an-automation","getting-started/7.create-an-automation","Get started using flows, triggers, operations and the data chain in Directus Automate.",{"title":472,"path":473,"stem":474,"description":475,"icon":14,"links":14},"Connect to Realtime Data","/getting-started/connect-to-realtime","getting-started/8.connect-to-realtime","This guide will cover connecting to Directus via WebSockets on the web, subscribing to changes, and creating new items over the connection.",{"title":477,"path":478,"stem":479,"description":480,"icon":14,"links":14},"Resources & Links","/getting-started/resources","getting-started/9.resources","Key links across the Directus ecosystem.",{"title":482,"path":483,"stem":484,"children":485,"page":89},"Guides","/guides","guides",[486,512,595,642,677,707,732,756,771,886,899,988],{"title":487,"description":14,"icon":488,"links":14,"path":489,"stem":490,"children":491,"page":89},"Data Model","directus-explore","/guides/data-model","guides/01.data-model",[492,497,502,507],{"title":493,"path":494,"stem":495,"description":496,"icon":14,"links":14},"Collections","/guides/data-model/collections","guides/01.data-model/1.collections","Directus collections help you manage your data. Create custom collections, define fields, configure relationships, and leverage features like content versioning and access control. Learn how to create, configure, and manage collections in Directus.",{"title":498,"path":499,"stem":500,"description":501,"icon":14,"links":14},"Fields","/guides/data-model/fields","guides/01.data-model/2.fields","Directus fields let you define how your data is stored and displayed. Learn about creating fields, data types, interfaces, validations, relationships, and more. Discover how to configure fields to perfectly suit your data modeling needs in Directus.",{"title":503,"path":504,"stem":505,"description":506,"icon":14,"links":14},"Interfaces","/guides/data-model/interfaces","guides/01.data-model/3.interfaces","Manage your data effectively with Directus fields. Discover various field types, interfaces, validations, and relationships to perfectly suit your data modeling needs.",{"title":508,"path":509,"stem":510,"description":511,"icon":14,"links":14},"Relationships","/guides/data-model/relationships","guides/01.data-model/4.relationships","Leverage Directus relationships to create powerful data connections. Explore Many to One, One to Many, Many to Many, and Many to Any relationships, along with Translations for multilingual content management.",{"title":513,"description":14,"icon":514,"links":14,"path":515,"stem":516,"children":517,"page":89},"Content","directus-editor","/guides/content","guides/02.content",[518,523,528,533,538,543,548,552,574],{"title":519,"path":520,"stem":521,"description":522,"icon":14,"links":14},"Collection Explorer","/guides/content/explore","guides/02.content/1.explore","Learn to filter, layout, batch edit and more with collections in the collection explorer.",{"title":524,"path":525,"stem":526,"description":527,"icon":14,"links":14},"Item Editor","/guides/content/editor","guides/02.content/2.editor","Learn to create, duplicate, archive and perform other actions with items using Directus.",{"title":529,"path":530,"stem":531,"description":532,"icon":14,"links":14},"Layouts","/guides/content/layouts","guides/02.content/3.layouts","Learn to use layouts for viewing and interacting with items in a collection using Directus.",{"title":534,"path":535,"stem":536,"description":537,"icon":14,"links":14},"Import & Export","/guides/content/import-export","guides/02.content/4.import-export","Learn to import and export multiple items stored as files using Directus.",{"title":539,"path":540,"stem":541,"description":542,"icon":14,"links":14},"Live Preview","/guides/content/live-preview","guides/02.content/5.live-preview","Learn to set up your project for live previewing items from your application.",{"title":544,"path":545,"stem":546,"description":547,"icon":14,"links":14},"Content Versioning","/guides/content/content-versioning","guides/02.content/6.content-versioning","This guide covers the process of enabling and utilizing Content Versioning in Directus.",{"title":255,"path":549,"stem":550,"description":551,"icon":14,"links":14},"/guides/content/translations","guides/02.content/7.translations","Both content and the data studio can be translated into multiple languages.",{"title":553,"path":554,"stem":555,"children":556,"description":558,"icon":14,"links":14},"Visual Editor","/guides/content/visual-editor","guides/02.content/8.visual-editor/0.index",[557,559,564,569],{"title":553,"path":554,"stem":555,"description":558,"icon":14,"links":14},"The Directus visual editor module allows you to visually edit the content of your website directly in-place.",{"title":560,"path":561,"stem":562,"description":563,"icon":14,"links":14},"Frontend Library","/guides/content/visual-editor/frontend-library","guides/02.content/8.visual-editor/1.frontend-library","A library that allows your website to communicate with your Directus project and enables Visual Editing.",{"title":565,"path":566,"stem":567,"description":568,"icon":14,"links":14},"Studio Module","/guides/content/visual-editor/studio-module","guides/02.content/8.visual-editor/2.studio-module","Learn how to edit your website's content in place from within the Directus Studio.",{"title":570,"path":571,"stem":572,"description":573,"icon":14,"links":14},"Customization","/guides/content/visual-editor/customization","guides/02.content/8.visual-editor/3.customization","Customize the styling of your Visual Editing experience to suit your brand or website theming.",{"title":575,"path":576,"stem":577,"children":578,"description":580,"icon":14,"links":14},"Collaborative Editing","/guides/content/collaborative-editing","guides/02.content/9.collaborative-editing/0.index",[579,581,585,590],{"title":575,"path":576,"stem":577,"description":580,"icon":14,"links":14},"Directus Collaborative Editing enables real-time data synchronization and collaborative editing across collections, allowing multiple users to edit content simultaneously without conflicts.",{"title":175,"path":582,"stem":583,"description":584,"icon":14,"links":14},"/guides/content/collaborative-editing/configuration","guides/02.content/9.collaborative-editing/1.configuration","Learn how to configure Collaborative Editing in your Directus project.",{"title":586,"path":587,"stem":588,"description":589,"icon":14,"links":14},"Usage Guide","/guides/content/collaborative-editing/usage","guides/02.content/9.collaborative-editing/2.usage","Learn how to use Collaborative Editing for real-time collaboration on content in your Directus project.",{"title":591,"path":592,"stem":593,"description":594,"icon":14,"links":14},"Development & Custom Extensions","/guides/content/collaborative-editing/development","guides/02.content/9.collaborative-editing/3.development","Learn how Custom Interfaces integrate with Collaborative Editing in Directus.",{"title":74,"description":14,"icon":596,"links":14,"path":597,"stem":598,"children":599,"page":89},"directus-auth","/guides/auth","guides/03.auth",[600,605,610,615,620,625,630],{"title":601,"path":602,"stem":603,"description":604,"icon":14,"links":14},"Access Tokens","/guides/auth/tokens-cookies","guides/03.auth/1.tokens-cookies","Learn how to authenticate requests & explore standard, session, and static token types.",{"title":606,"path":607,"stem":608,"description":609,"icon":14,"links":14},"Access Control","/guides/auth/access-control","guides/03.auth/2.access-control","Manage user and role permissions and policies for interacting with data in Directus.",{"title":611,"path":612,"stem":613,"description":614,"icon":14,"links":14},"Creating Users","/guides/auth/creating-users","guides/03.auth/3.creating-users","Learn about creating users in directus, including API creation, inviting users, and seamless invites.",{"title":616,"path":617,"stem":618,"description":619,"icon":14,"links":14},"Email Login","/guides/auth/email-login","guides/03.auth/4.email-login","Learn about user registration, login with standard/session tokens, refresh, logout, and resetting passwords.",{"title":621,"path":622,"stem":623,"description":624,"icon":14,"links":14},"Two-Factor Auth","/guides/auth/2fa","guides/03.auth/5.2fa","Secure your logins with one-time codes! Learn how to generate secrets, enable/disable 2FA.",{"title":626,"path":627,"stem":628,"description":629,"icon":14,"links":14},"Accountability","/guides/auth/accountability","guides/03.auth/6.accountability","Learn to audit user activity and enforce accountability using the activity feed.",{"title":631,"path":632,"stem":633,"children":634,"description":636,"icon":14,"links":14},"Single Sign-On","/guides/auth/sso","guides/03.auth/7.sso/1.index",[635,637],{"title":631,"path":632,"stem":633,"description":636,"icon":14,"links":14},"Single Sign-On is a mechanism which allows to use external providers to login into systems.",{"title":638,"path":639,"stem":640,"description":641,"icon":14,"links":14},"Seamless SSO","/guides/auth/sso/seamless","guides/03.auth/7.sso/2.seamless","Seamless SSO is a setup to allow logging in without the user ever seeing Directus' login page.",{"title":643,"description":14,"icon":644,"links":14,"path":645,"stem":646,"children":647,"page":89},"Connect","directus-connect","/guides/connect","guides/04.connect",[648,652,657,662,667,672],{"title":16,"path":649,"stem":650,"description":651,"icon":14,"links":14},"/guides/connect/authentication","guides/04.connect/1.authentication","Discover how to authenticate Directus Connect requests using authorization headers, session cookies, or query parameters.",{"title":653,"path":654,"stem":655,"description":656,"icon":14,"links":14},"Filter Rules","/guides/connect/filter-rules","guides/04.connect/2.filter-rules","Learn about filter rules in Directus - available operators, filter syntax, relational fields, dynamic variables, logical operators, and functions parameters. Understand how to build complex filters for permissions, validations, and automations.",{"title":658,"path":659,"stem":660,"description":661,"icon":14,"links":14},"Query Parameters","/guides/connect/query-parameters","guides/04.connect/3.query-parameters","Learn about Directus query parameters - fields, filter, search, sort, limit, offset, page, aggregate, groupBy, deep, alias, and export. Understand how to customize your API requests and retrieve specific data from your collections.",{"title":663,"path":664,"stem":665,"description":666,"icon":14,"links":14},"Relational Data","/guides/connect/relations","guides/04.connect/4.relations","Directus enables you to manage and interact with relational data. This section will guide you through the different types of relationships and how to work with them.",{"title":668,"path":669,"stem":670,"description":671,"icon":14,"links":14},"Error Codes","/guides/connect/errors","guides/04.connect/5.errors","Learn about Directus error codes - understand what each code means, from validation failures to rate limits exceeded. Troubleshoot issues with your API requests and resolve errors efficiently.",{"title":673,"path":674,"stem":675,"description":676,"icon":14,"links":14},"Directus SDK","/guides/connect/sdk","guides/04.connect/6.sdk","A JavaScript and TypeScript library that simplifies working with Directus.",{"title":377,"description":14,"icon":678,"links":14,"path":679,"stem":680,"children":681,"page":89},"directus-files","/guides/files","guides/05.files",[682,687,692,697,702],{"title":683,"path":684,"stem":685,"description":686,"icon":14,"links":14},"Upload Files","/guides/files/upload","guides/05.files/1.upload","Learn to upload files to Directus via both the data studio or API.",{"title":688,"path":689,"stem":690,"description":691,"icon":14,"links":14},"Download Files","/guides/files/download","guides/05.files/2.download","Learn to download content from the File Library",{"title":693,"path":694,"stem":695,"description":696,"icon":14,"links":14},"Manage Files","/guides/files/manage","guides/05.files/3.manage","Learn to view, modify, edit and set files' focal points.",{"title":698,"path":699,"stem":700,"description":701,"icon":14,"links":14},"Access Files","/guides/files/access","guides/05.files/4.access","Learn how to access uploaded files, authenticate, provide optional filenames and directly download them.",{"title":703,"path":704,"stem":705,"description":706,"icon":14,"links":14},"Transform Files","/guides/files/transform","guides/05.files/5.transform","Learn how to transform files and set custom presets for these transformations.",{"title":708,"description":14,"icon":709,"links":14,"path":710,"stem":711,"children":712,"page":89},"Automate","directus-automate","/guides/automate","guides/06.automate",[713,717,722,727],{"title":382,"path":714,"stem":715,"description":716,"icon":14,"links":14},"/guides/automate/flows","guides/06.automate/1.flows","Flows enable custom, event-driven data processing and task automation within Directus.",{"title":718,"path":719,"stem":720,"description":721,"icon":14,"links":14},"Data Chain","/guides/automate/data-chain","guides/06.automate/2.data-chain","Data chains are created by each flow and hold information that can be accessed within different operations.",{"title":723,"path":724,"stem":725,"description":726,"icon":14,"links":14},"Triggers","/guides/automate/triggers","guides/06.automate/3.triggers","Triggers define the action or events that start flows.",{"title":728,"path":729,"stem":730,"description":731,"icon":14,"links":14},"Operations","/guides/automate/operations","guides/06.automate/4.operations","Operations are individual customizable actions in a flow.",{"title":86,"description":14,"icon":733,"links":14,"path":734,"stem":735,"children":736,"page":89},"directus-realtime","/guides/realtime","guides/07.realtime",[737,741,746,751],{"title":16,"path":738,"stem":739,"description":740,"icon":14,"links":14},"/guides/realtime/authentication","guides/07.realtime/1.authentication","Learn to implement the three authentication modes.",{"title":742,"path":743,"stem":744,"description":745,"icon":14,"links":14},"Subscriptions","/guides/realtime/subscriptions","guides/07.realtime/2.subscriptions","Learn to manage realtime subscriptions with both websockets and GraphQL.",{"title":747,"path":748,"stem":749,"description":750,"icon":14,"links":14},"Actions","/guides/realtime/actions","guides/07.realtime/3.actions","Learn to execute CRUD actions via websockets.",{"title":752,"path":753,"stem":754,"description":755,"icon":14,"links":14},"Custom WebSocket Handlers","/guides/realtime/custom-handlers","guides/07.realtime/4.custom-handlers","Build custom WebSocket message handlers, push messages to connected clients, and react to WebSocket events using hook extensions.",{"title":757,"description":14,"icon":758,"links":14,"path":759,"stem":760,"children":761,"page":89},"Insights","directus-insights","/guides/insights","guides/08.insights",[762,766],{"title":230,"path":763,"stem":764,"description":765,"icon":14,"links":14},"/guides/insights/overview","guides/08.insights/1.overview","Insights is a module in Directus that allows rapid, no-code build-out of analytics dashboards.",{"title":767,"path":768,"stem":769,"description":770,"icon":14,"links":14},"Panels","/guides/insights/panels","guides/08.insights/2.panels","Panels are the building-blocks you can add onto insights dashboards to create, save and display data analytics.",{"title":372,"description":14,"icon":772,"links":14,"path":773,"stem":774,"children":775,"page":89},"directus-marketplace","/guides/extensions","guides/09.extensions",[776,780,785,817,864,869,881],{"title":230,"path":777,"stem":778,"description":779,"icon":14,"links":14},"/guides/extensions/overview","guides/09.extensions/0.overview","Extensions are used to extend the functionality of Directus.",{"title":781,"path":782,"stem":783,"description":784,"icon":14,"links":14},"Quickstart","/guides/extensions/quickstart","guides/09.extensions/1.quickstart","This guide will cover how to get started with developing an extension for Directus.",{"title":786,"path":787,"stem":788,"children":789,"description":791,"icon":14,"links":14},"API Extensions","/guides/extensions/api-extensions","guides/09.extensions/2.api-extensions/0.index",[790,792,797,802,807,812],{"title":786,"path":787,"stem":788,"description":791,"icon":14,"links":14},"API Extensions extend the functionality of the API.",{"title":793,"path":794,"stem":795,"description":796,"icon":14,"links":14},"Event Hooks","/guides/extensions/api-extensions/hooks","guides/09.extensions/2.api-extensions/1.hooks","Hooks allow running code when during the Directus lifecycle or database events.",{"title":798,"path":799,"stem":800,"description":801,"icon":14,"links":14},"API Endpoints","/guides/extensions/api-extensions/endpoints","guides/09.extensions/2.api-extensions/2.endpoints","Endpoints allow you to register new API routes in your Directus project.",{"title":803,"path":804,"stem":805,"description":806,"icon":14,"links":14},"Flow Operations","/guides/extensions/api-extensions/operations","guides/09.extensions/2.api-extensions/3.operations","Operations are single steps in a Flow - the no-code automation tool part of Directus Automate.",{"title":808,"path":809,"stem":810,"description":811,"icon":14,"links":14},"Services","/guides/extensions/api-extensions/services","guides/09.extensions/2.api-extensions/4.services","When building extensions, you may use internal Directus services directly.",{"title":813,"path":814,"stem":815,"description":816,"icon":14,"links":14},"Sandbox","/guides/extensions/api-extensions/sandbox","guides/09.extensions/2.api-extensions/5.sandbox","Sandboxed Extensions run in an isolated environment and must request permission scopes.",{"title":818,"path":819,"stem":820,"children":821,"description":823,"icon":14,"links":14},"App Extensions","/guides/extensions/app-extensions","guides/09.extensions/3.app-extensions/0.index",[822,824,829,834,839,844,849,854,859],{"title":818,"path":819,"stem":820,"description":823,"icon":14,"links":14},"App Extensions extend the functionality of the Data Studio.",{"title":825,"path":826,"stem":827,"description":828,"icon":14,"links":14},"Editor Interfaces","/guides/extensions/app-extensions/interfaces","guides/09.extensions/3.app-extensions/1.interfaces","Interfaces are form inputs used primarily inside of the Directus Editor.",{"title":830,"path":831,"stem":832,"description":833,"icon":14,"links":14},"Inline Displays","/guides/extensions/app-extensions/displays","guides/09.extensions/3.app-extensions/2.displays","Displays are used to display a single value throughout the Data Studio.",{"title":835,"path":836,"stem":837,"description":838,"icon":14,"links":14},"Explore Layouts","/guides/extensions/app-extensions/layouts","guides/09.extensions/3.app-extensions/3.layouts","Layouts are used to display a list of items in Explore pages in different ways.",{"title":840,"path":841,"stem":842,"description":843,"icon":14,"links":14},"Dashboard Panels","/guides/extensions/app-extensions/panels","guides/09.extensions/3.app-extensions/4.panels","Panels are customizable components within Directus Insights dashboards.",{"title":845,"path":846,"stem":847,"description":848,"icon":14,"links":14},"Custom Modules","/guides/extensions/app-extensions/modules","guides/09.extensions/3.app-extensions/5.modules","Modules are top-level areas of the Data Studio, navigated to from the left-hand module bar.",{"title":850,"path":851,"stem":852,"description":853,"icon":14,"links":14},"Custom Themes","/guides/extensions/app-extensions/themes","guides/09.extensions/3.app-extensions/6.themes","Themes are used to style elements of the Data Studio including colors and fonts.",{"title":855,"path":856,"stem":857,"description":858,"icon":14,"links":14},"UI Library","/guides/extensions/app-extensions/ui-library","guides/09.extensions/3.app-extensions/7.ui-library","Directus offers globally-registered UI components for building extensions.",{"title":860,"path":861,"stem":862,"description":863,"icon":14,"links":14},"Composables","/guides/extensions/app-extensions/composables","guides/09.extensions/3.app-extensions/8.composables","Vue composables for working with Directus services when building extensions.",{"title":865,"path":866,"stem":867,"description":868,"icon":14,"links":14},"Bundling Extensions","/guides/extensions/bundles","guides/09.extensions/4.bundles","Bundles are a way to group extensions together as a single distributable package.",{"title":870,"path":871,"stem":872,"children":873,"description":875,"icon":14,"links":14},"Marketplace Beta","/guides/extensions/marketplace","guides/09.extensions/5.marketplace/0.index",[874,876],{"title":870,"path":871,"stem":872,"description":875,"icon":14,"links":14},"The Directus Marketplace provides a way for users to install extensions in their projects directly the Data Studio.",{"title":877,"path":878,"stem":879,"description":880,"icon":14,"links":14},"Publishing Extensions","/guides/extensions/marketplace/publishing","guides/09.extensions/5.marketplace/1.publishing","Publish extensions to the Directus Marketplace via npm, including required metadata, best practices, and author profile setup.",{"title":882,"path":883,"stem":884,"description":885,"icon":14,"links":14},"CLI","/guides/extensions/cli","guides/09.extensions/6.cli","Using the create-directus-extension to build, validate and manage extensions.",{"title":887,"path":888,"stem":889,"children":890,"description":14,"icon":898,"links":14},"Deployments","/guides/deployments","guides/10.deployments/0.index",[891,893],{"title":230,"path":888,"stem":889,"description":892,"icon":14,"links":14},"Trigger, monitor, and manage frontend deployments directly from Directus.",{"title":894,"path":895,"stem":896,"description":897,"icon":14,"links":14},"Security","/guides/deployments/security","guides/10.deployments/1.security","Access control, permissions, and credential protection for the Deployment module.","directus-deployments",{"title":347,"path":900,"stem":901,"children":902,"description":14,"icon":987,"links":14},"/guides/ai","guides/11.ai/0.index",[903,906,937],{"title":904,"path":900,"stem":901,"description":905,"icon":14,"links":14},"AI + Directus","Use AI to interact with Directus - either through the built-in AI Assistant or by connecting external AI tools via MCP.",{"title":907,"path":908,"stem":909,"children":910,"description":14,"icon":14,"links":14},"AI Assistant","/guides/ai/assistant","guides/11.ai/1.assistant/0.index",[911,913,918,923,928,933],{"title":230,"path":908,"stem":909,"description":912,"icon":14,"links":14},"Chat with an AI assistant directly inside Directus. Create content, manage your schema, trigger automations, and explore your data through natural conversation.",{"title":914,"path":915,"stem":916,"description":917,"icon":14,"links":14},"Setup","/guides/ai/assistant/setup","guides/11.ai/1.assistant/1.setup","Configure AI Assistant by adding your AI provider API keys and customizing assistant behavior.",{"title":919,"path":920,"stem":921,"description":922,"icon":14,"links":14},"Usage","/guides/ai/assistant/usage","guides/11.ai/1.assistant/2.usage","Learn how to use AI Assistant to interact with your Directus instance through natural conversation.",{"title":924,"path":925,"stem":926,"description":927,"icon":14,"links":14},"Tools","/guides/ai/assistant/tools","guides/11.ai/1.assistant/3.tools","Reference of all tools available to AI Assistant for interacting with your Directus instance.",{"title":929,"path":930,"stem":931,"description":932,"icon":14,"links":14},"Best Practices","/guides/ai/assistant/tips","guides/11.ai/1.assistant/4.tips","Get the most out of AI Assistant with practical tips, example prompts, and common pitfalls to avoid.",{"title":894,"path":934,"stem":935,"description":936,"icon":14,"links":14},"/guides/ai/assistant/security","guides/11.ai/1.assistant/5.security","Security considerations for using AI Assistant safely with your Directus data.",{"title":938,"path":939,"stem":940,"children":941,"description":14,"icon":14,"links":14},"MCP Server","/guides/ai/mcp","guides/11.ai/2.mcp/0.index",[942,944,949,954,958,963,968,972],{"title":230,"path":939,"stem":940,"description":943,"icon":14,"links":14},"Connect AI assistants directly to your Directus instance. Let Claude, ChatGPT, and other AI tools manage your content without manual copy-pasting.",{"title":945,"path":946,"stem":947,"description":948,"icon":14,"links":14},"Installation","/guides/ai/mcp/installation","guides/11.ai/2.mcp/1.installation","Set up the Directus MCP server and connect your AI tools in under 5 minutes.",{"title":950,"path":951,"stem":952,"description":953,"icon":14,"links":14},"Use Cases","/guides/ai/mcp/use-cases","guides/11.ai/2.mcp/2.use-cases","Real examples of how to use AI with your Directus content to save time and reduce repetitive work.",{"title":924,"path":955,"stem":956,"description":957,"icon":14,"links":14},"/guides/ai/mcp/tools","guides/11.ai/2.mcp/3.tools","Learn about the tools available in the Directus remote MCP server and how they enable AI-powered content management.",{"title":959,"path":960,"stem":961,"description":962,"icon":14,"links":14},"Prompts","/guides/ai/mcp/prompts","guides/11.ai/2.mcp/4.prompts","Learn how to configure and use stored prompts with the Directus MCP Server.",{"title":964,"path":965,"stem":966,"description":967,"icon":14,"links":14},"Troubleshooting","/guides/ai/mcp/troubleshooting","guides/11.ai/2.mcp/5.troubleshooting","Common issues and solutions when setting up and using the Directus MCP server.",{"title":894,"path":969,"stem":970,"description":971,"icon":14,"links":14},"/guides/ai/mcp/security","guides/11.ai/2.mcp/6.security","Practical security guidelines for using the Directus MCP server safely and protecting your data.",{"title":973,"path":974,"stem":975,"children":976,"description":14,"icon":14,"links":14},"Local MCP","/guides/ai/mcp/local-mcp","guides/11.ai/2.mcp/7.local-mcp/0.index",[977,979,983],{"title":945,"path":974,"stem":975,"description":978,"icon":14,"links":14},"The Directus Content MCP Server allows you to interact with your Directus data through AI tools using the Model Context Protocol.",{"title":924,"path":980,"stem":981,"description":982,"icon":14,"links":14},"/guides/ai/mcp/local-mcp/tools","guides/11.ai/2.mcp/7.local-mcp/1.tools","Learn about the tools available in the local Directus Content MCP Server and how to configure them.",{"title":959,"path":984,"stem":985,"description":986,"icon":14,"links":14},"/guides/ai/mcp/local-mcp/prompts","guides/11.ai/2.mcp/7.local-mcp/2.prompts","Configure stored prompts with the local MCP server using environment variables and manual collection setup.","directus-ai",{"title":989,"description":14,"icon":990,"links":14,"path":991,"stem":992,"children":993},"Integrations","directus-integrations","/guides/integrations","guides/12.integrations/index",[994,996,1003,1024,1046,1065,1076],{"title":989,"path":991,"stem":992,"description":995,"icon":14,"links":14},"Connect Directus with third-party tools and services to extend functionality and automate workflows.",{"title":997,"path":998,"stem":999,"children":1000,"description":14,"icon":14,"links":14},"Framer","/guides/integrations/framer","guides/11.integrations/6.framer/0.index",[1001],{"title":997,"path":998,"stem":999,"description":1002,"icon":14,"links":14},"Connect your Directus collections to Framer's CMS to sync content in both directions using the Directus Framer plugin.",{"title":1004,"path":1005,"stem":1006,"children":1007,"description":14,"icon":14,"links":14},"n8n","/guides/integrations/n8n","guides/12.integrations/1.n8n/0.index",[1008,1011,1015,1020],{"title":1009,"path":1005,"stem":1006,"description":1010,"icon":14,"links":14},"Integration","Connect Directus with n8n to automate workflows, sync data, and integrate your CMS with other services using the Directus community node.",{"title":747,"path":1012,"stem":1013,"description":1014,"icon":14,"links":14},"/guides/integrations/n8n/directus-n8n-actions","guides/12.integrations/1.n8n/directus-n8n-actions","Complete guide for using Directus actions in n8n workflows, including working with items, users, and files.",{"title":1016,"path":1017,"stem":1018,"description":1019,"icon":14,"links":14},"Advanced","/guides/integrations/n8n/directus-n8n-advanced","guides/12.integrations/1.n8n/directus-n8n-advanced","Advanced guide for using Directus raw CRUD operations in n8n, including raw JSON operations, complex filters, relational queries, and query parameters.",{"title":723,"path":1021,"stem":1022,"description":1023,"icon":14,"links":14},"/guides/integrations/n8n/directus-n8n-triggers","guides/12.integrations/1.n8n/directus-n8n-triggers","Complete guide for using Directus triggers in n8n workflows to automate workflows when events happen in Directus.",{"title":1025,"path":1026,"stem":1027,"children":1028,"description":14,"icon":14,"links":14},"Clay","/guides/integrations/clay","guides/12.integrations/2.clay/0.index",[1029,1031,1036,1041],{"title":1009,"path":1026,"stem":1027,"description":1030,"icon":14,"links":14},"Connect Directus with Clay to automate data enrichment and sync content between platforms using webhooks and HTTP API templates.",{"title":1032,"path":1033,"stem":1034,"description":1035,"icon":14,"links":14},"Data Operations","/guides/integrations/clay/directus-clay-data-operations","guides/12.integrations/2.clay/directus-clay-data-operations","Advanced techniques for working with Directus data in Clay, including filters, pagination, common use cases, and best practices.",{"title":1037,"path":1038,"stem":1039,"description":1040,"icon":14,"links":14},"Templates","/guides/integrations/clay/use-clay-templates-with-directus","guides/12.integrations/2.clay/use-clay-templates-with-directus","Learn how to use Clay's pre-built HTTP API templates to connect with Directus for data enrichment and synchronization.",{"title":1042,"path":1043,"stem":1044,"description":1045,"icon":14,"links":14},"Webhooks","/guides/integrations/clay/use-directus-webhooks-with-clay","guides/12.integrations/2.clay/use-directus-webhooks-with-clay","Learn how to set up Directus Flows to automatically send data to Clay webhooks for real-time data synchronization.",{"title":1047,"path":1048,"stem":1049,"children":1050,"description":14,"icon":14,"links":14},"Zapier","/guides/integrations/zapier","guides/12.integrations/3.zapier/0.index",[1051,1053,1057,1061],{"title":1009,"path":1048,"stem":1049,"description":1052,"icon":14,"links":14},"Connect Directus with Zapier to automate workflows, sync data, and integrate your CMS with thousands of other apps using the Directus Zapier integration.",{"title":747,"path":1054,"stem":1055,"description":1056,"icon":14,"links":14},"/guides/integrations/zapier/actions","guides/12.integrations/3.zapier/actions","Complete guide for using Directus actions in Zapier workflows, including working with items, users, and files.",{"title":1016,"path":1058,"stem":1059,"description":1060,"icon":14,"links":14},"/guides/integrations/zapier/advanced","guides/12.integrations/3.zapier/advanced","Advanced guide for using Directus API features in Zapier, including raw request actions, advanced filtering, and custom API calls.",{"title":723,"path":1062,"stem":1063,"description":1064,"icon":14,"links":14},"/guides/integrations/zapier/triggers","guides/12.integrations/3.zapier/triggers","Complete guide for using Directus triggers in Zapier workflows to automatically start Zaps when events happen in Directus.",{"title":1066,"path":1067,"stem":1068,"children":1069,"description":14,"icon":14,"links":14},"Vercel","/guides/integrations/vercel","guides/12.integrations/4.vercel/0.index",[1070,1072],{"title":1066,"path":1067,"stem":1068,"description":1071,"icon":14,"links":14},"Connect Directus with Vercel to trigger deployments, monitor build status, and manage your frontend projects directly from your Directus instance.",{"title":887,"path":1073,"stem":1074,"description":1075,"icon":14,"links":14},"/guides/integrations/vercel/deployments","guides/12.integrations/4.vercel/deployments","Complete guide for triggering deployments, monitoring build status, and viewing logs for your Vercel projects from Directus.",{"title":1077,"path":1078,"stem":1079,"children":1080,"description":14,"icon":14,"links":14},"Netlify","/guides/integrations/netlify","guides/12.integrations/5.netlify/0.index",[1081,1083],{"title":1077,"path":1078,"stem":1079,"description":1082,"icon":14,"links":14},"Integrate Directus with Netlify to deploy your sites, track build progress, and manage frontend projects from within your Directus instance.",{"title":887,"path":1084,"stem":1085,"description":1086,"icon":14,"links":14},"/guides/integrations/netlify/deployments","guides/12.integrations/5.netlify/deployments","Full guide for triggering builds, tracking deployment progress, and viewing logs for your Netlify sites from Directus.",{"title":230,"path":1088,"stem":1089,"children":1090,"description":1092,"icon":14,"links":14},"/releases","releases/1.index",[1091,1093,1098],{"title":230,"path":1088,"stem":1089,"description":1092,"icon":14,"links":14},"Releases are how we roll out new features, updates, and fixes to Directus.",{"title":1094,"path":1095,"stem":1096,"description":1097,"icon":14,"links":14},"Changelog","/releases/changelog","releases/2.changelog","A monthly summary of what's new from the Directus team.",{"title":1099,"path":1100,"stem":1101,"children":1102,"description":1104,"icon":14,"links":14},"Breaking Changes","/releases/breaking-changes","releases/3.breaking-changes/0.index",[1103,1105,1109],{"title":1099,"path":1100,"stem":1101,"description":1104,"icon":14,"links":14},"Breaking changes may require action on your part before upgrading.",{"title":1106,"path":1107,"stem":1108,"description":1104,"icon":14,"links":14},"Version 10","/releases/breaking-changes/version-10","releases/3.breaking-changes/1.version-10",{"title":1110,"path":1111,"stem":1112,"description":1104,"icon":14,"links":14},"Version 11","/releases/breaking-changes/version-11","releases/3.breaking-changes/2.version-11",{"title":1114,"description":14,"icon":14,"links":14,"path":1115,"stem":1116,"children":1117,"page":89},"Self-Hosting","/self-hosting","self-hosting",[1118,1122,1127,1132,1137],{"title":230,"path":1119,"stem":1120,"description":1121,"icon":14,"links":14},"/self-hosting/overview","self-hosting/1.overview","Self-hosting Directus means running the Directus software on your own infrastructure.",{"title":1123,"path":1124,"stem":1125,"description":1126,"icon":14,"links":14},"Requirements","/self-hosting/requirements","self-hosting/2.requirements","This page outlines the requirements for self-hosting Directus.",{"title":1128,"path":1129,"stem":1130,"description":1131,"icon":14,"links":14},"Deployment","/self-hosting/deploying","self-hosting/3.deploying","This section covers the deployment process of Directus, including environment variables, versioning, persistence, and initial admin user setup.",{"title":1133,"path":1134,"stem":1135,"description":1136,"icon":14,"links":14},"Upgrading","/self-hosting/upgrading","self-hosting/4.upgrading","Learn how to upgrade Directus to the latest version.",{"title":1138,"path":1139,"stem":1140,"description":1141,"icon":14,"links":14},"Including Extensions","/self-hosting/including-extensions","self-hosting/5.including-extensions","Learn how to include extensions in your self-hosted Directus project.",{"title":1143,"path":1144,"stem":1145,"children":1146},"Tutorials","/tutorials","tutorials",[1147,1150,1370,1530,1576,1602,1719,1749],{"title":1143,"path":1144,"stem":1148,"description":1149,"icon":14,"links":14},"tutorials/index","This is a collection of step-by-step guides and practical examples to help you get the most out of our platform. Whether you're a beginner or an experienced user, our tutorials are designed to provide you with the knowledge and skills you need to succeed.",{"title":125,"path":1151,"stem":1152,"children":1153,"description":24,"icon":14,"links":14},"/tutorials/getting-started","tutorials/1.getting-started/index",[1154,1155,1160,1165,1170,1175,1180,1185,1190,1195,1200,1205,1210,1215,1220,1225,1230,1235,1240,1245,1250,1255,1260,1265,1270,1275,1280,1285,1290,1295,1300,1305,1310,1315,1320,1325,1330,1335,1340,1345,1350,1355,1360,1365],{"title":125,"path":1151,"stem":1152,"description":24,"icon":14,"links":14},{"title":1156,"path":1157,"stem":1158,"description":1159,"icon":14,"links":14},"Create Reusable Blocks with Many-to-Any Relationships","/tutorials/getting-started/create-reusable-blocks-with-many-to-any-relationships","tutorials/1.getting-started/create-reusable-blocks-with-many-to-any-relationships","Learn how to data model for multiple, repeating sections of content.",{"title":1161,"path":1162,"stem":1163,"description":1164,"icon":14,"links":14},"Fetch Data from Directus in Android with Kotlin","/tutorials/getting-started/fetch-data-from-directus-in-android-with-kotlin","tutorials/1.getting-started/fetch-data-from-directus-in-android-with-kotlin","Learn how to integrate Directus in your Android app with Kotlin.",{"title":1166,"path":1167,"stem":1168,"description":1169,"icon":14,"links":14},"Fetch Data from Directus in iOS with Swift","/tutorials/getting-started/fetch-data-from-directus-in-ios-with-swift","tutorials/1.getting-started/fetch-data-from-directus-in-ios-with-swift","Learn how to integrate Directus in your iOS app with Swift.",{"title":1171,"path":1172,"stem":1173,"description":1174,"icon":14,"links":14},"Fetch Data from Directus with Angular","/tutorials/getting-started/fetch-data-from-directus-with-angular","tutorials/1.getting-started/fetch-data-from-directus-with-angular","Learn how to integrate Directus in your Angular web application.",{"title":1176,"path":1177,"stem":1178,"description":1179,"icon":14,"links":14},"Fetch Data from Directus with Astro","/tutorials/getting-started/fetch-data-from-directus-with-astro","tutorials/1.getting-started/fetch-data-from-directus-with-astro","Learn how to integrate Directus in your Astro web application.",{"title":1181,"path":1182,"stem":1183,"description":1184,"icon":14,"links":14},"Fetch Data from Directus with Django","/tutorials/getting-started/fetch-data-from-directus-with-django","tutorials/1.getting-started/fetch-data-from-directus-with-django","Learn how to integrate Directus in your Django web application.",{"title":1186,"path":1187,"stem":1188,"description":1189,"icon":14,"links":14},"Fetch Data from Directus with Eleventy 3","/tutorials/getting-started/fetch-data-from-directus-with-eleventy-3","tutorials/1.getting-started/fetch-data-from-directus-with-eleventy-3","Learn how to integrate Directus in your 11ty web application.",{"title":1191,"path":1192,"stem":1193,"description":1194,"icon":14,"links":14},"Fetch Data from Directus with Flask","/tutorials/getting-started/fetch-data-from-directus-with-flask","tutorials/1.getting-started/fetch-data-from-directus-with-flask","Learn how to integrate Directus in your Flask web application.",{"title":1196,"path":1197,"stem":1198,"description":1199,"icon":14,"links":14},"Fetch Data from Directus with Flutter","/tutorials/getting-started/fetch-data-from-directus-with-flutter","tutorials/1.getting-started/fetch-data-from-directus-with-flutter","Learn how to integrate Directus in your Flutter app with Dart.",{"title":1201,"path":1202,"stem":1203,"description":1204,"icon":14,"links":14},"Fetch Data from Directus with Laravel","/tutorials/getting-started/fetch-data-from-directus-with-laravel","tutorials/1.getting-started/fetch-data-from-directus-with-laravel","Learn how to integrate Directus in your Laravel web application.",{"title":1206,"path":1207,"stem":1208,"description":1209,"icon":14,"links":14},"Fetch Data from Directus with Next.js","/tutorials/getting-started/fetch-data-from-directus-with-nextjs","tutorials/1.getting-started/fetch-data-from-directus-with-nextjs","Learn how to integrate Directus in your Next.js web application.",{"title":1211,"path":1212,"stem":1213,"description":1214,"icon":14,"links":14},"Fetch Data from Directus with Nuxt","/tutorials/getting-started/fetch-data-from-directus-with-nuxt","tutorials/1.getting-started/fetch-data-from-directus-with-nuxt","Learn how to integrate Directus in your Nuxt web application.",{"title":1216,"path":1217,"stem":1218,"description":1219,"icon":14,"links":14},"Fetch Data from Directus with SolidStart","/tutorials/getting-started/fetch-data-from-directus-with-solidstart","tutorials/1.getting-started/fetch-data-from-directus-with-solidstart","Learn how to integrate Directus in your SolidStart web application.",{"title":1221,"path":1222,"stem":1223,"description":1224,"icon":14,"links":14},"Fetch Data from Directus with Spring Boot","/tutorials/getting-started/fetch-data-from-directus-with-spring-boot","tutorials/1.getting-started/fetch-data-from-directus-with-spring-boot","Learn how to integrate Directus in your Spring Boot web application.",{"title":1226,"path":1227,"stem":1228,"description":1229,"icon":14,"links":14},"Fetch Data from Directus with SvelteKit","/tutorials/getting-started/fetch-data-from-directus-with-sveltekit","tutorials/1.getting-started/fetch-data-from-directus-with-sveltekit","Learn how to integrate Directus in your SvelteKit web application.",{"title":1231,"path":1232,"stem":1233,"description":1234,"icon":14,"links":14},"Implement Directus Auth with iOS","/tutorials/getting-started/implement-directus-auth-with-ios","tutorials/1.getting-started/implement-directus-auth-with-ios","Learn how to register, login, and protect content in your iOS app.",{"title":1236,"path":1237,"stem":1238,"description":1239,"icon":14,"links":14},"Implement Multilingual Content with Directus and SvelteKit","/tutorials/getting-started/implement-multilingual-content-with-directus-and-svelte-kit","tutorials/1.getting-started/implement-multilingual-content-with-directus-and-svelte-kit","Learn how to handle internationalization in your SvelteKit application.",{"title":1241,"path":1242,"stem":1243,"description":1244,"icon":14,"links":14},"Implementing Live Preview in Astro","/tutorials/getting-started/implementing-live-preview-in-astro","tutorials/1.getting-started/implementing-live-preview-in-astro","Learn how to setup Directus live preview with Astro.",{"title":1246,"path":1247,"stem":1248,"description":1249,"icon":14,"links":14},"Implementing Live Preview in Next.js","/tutorials/getting-started/implementing-live-preview-in-next-js","tutorials/1.getting-started/implementing-live-preview-in-next-js","Learn how to setup Directus live preview with Next.js.",{"title":1251,"path":1252,"stem":1253,"description":1254,"icon":14,"links":14},"Implementing Live Preview in Nuxt","/tutorials/getting-started/implementing-live-preview-in-nuxt","tutorials/1.getting-started/implementing-live-preview-in-nuxt","Learn how to setup Directus live preview with Nuxt.",{"title":1256,"path":1257,"stem":1258,"description":1259,"icon":14,"links":14},"Implementing Live Preview in React","/tutorials/getting-started/implementing-live-preview-in-react","tutorials/1.getting-started/implementing-live-preview-in-react","Learn how to setup Directus live preview with React.",{"title":1261,"path":1262,"stem":1263,"description":1264,"icon":14,"links":14},"Implementing Live Preview in SvelteKit","/tutorials/getting-started/implementing-live-preview-in-sveltekit","tutorials/1.getting-started/implementing-live-preview-in-sveltekit","Learn how to setup Directus live preview with SvelteKit.",{"title":1266,"path":1267,"stem":1268,"description":1269,"icon":14,"links":14},"Implementing Multilingual Content using Directus and Astro","/tutorials/getting-started/implementing-multilingual-content-using-directus-and-astro","tutorials/1.getting-started/implementing-multilingual-content-using-directus-and-astro","Learn how to access multilingual Directus content using Astro.",{"title":1271,"path":1272,"stem":1273,"description":1274,"icon":14,"links":14},"Implementing Multilingual Content using Directus and Next.js","/tutorials/getting-started/implementing-multilingual-content-using-directus-and-next","tutorials/1.getting-started/implementing-multilingual-content-using-directus-and-next","Learn how to access multilingual Directus content using Next.js.",{"title":1276,"path":1277,"stem":1278,"description":1279,"icon":14,"links":14},"Implementing Multilingual Content using Directus and Nuxt","/tutorials/getting-started/implementing-multilingual-content-using-directus-and-nuxt","tutorials/1.getting-started/implementing-multilingual-content-using-directus-and-nuxt","Learn how to access multilingual Directus content using Nuxt.",{"title":1281,"path":1282,"stem":1283,"description":1284,"icon":14,"links":14},"Implementing Multilingual Content using Directus and SvelteKit","/tutorials/getting-started/implementing-multilingual-content-using-directus-and-sveltekit","tutorials/1.getting-started/implementing-multilingual-content-using-directus-and-sveltekit","Learn how to access multilingual Directus content using SvelteKit.",{"title":1286,"path":1287,"stem":1288,"description":1289,"icon":14,"links":14},"Integrating the Directus Visual Editor with Next.js","/tutorials/getting-started/integrating-the-directus-visual-editor-with-nextjs","tutorials/1.getting-started/integrating-the-directus-visual-editor-with-nextjs","Learn how to integrate the Directus Visual Editor with Next.js.",{"title":1291,"path":1292,"stem":1293,"description":1294,"icon":14,"links":14},"Integrating the Directus Visual Editor with Nuxt","/tutorials/getting-started/integrating-the-directus-visual-editor-with-nuxt","tutorials/1.getting-started/integrating-the-directus-visual-editor-with-nuxt","Learn how to integrate the Directus Visual Editor with Nuxt.",{"title":1296,"path":1297,"stem":1298,"description":1299,"icon":14,"links":14},"Integrating the Directus Visual Editor with SvelteKit","/tutorials/getting-started/integrating-the-directus-visual-editor-with-sveltekit","tutorials/1.getting-started/integrating-the-directus-visual-editor-with-sveltekit","Learn how to integrate the Directus Visual Editor with SvelteKit.",{"title":1301,"path":1302,"stem":1303,"description":1304,"icon":14,"links":14},"Rendering Dynamic Blocks Using Astro","/tutorials/getting-started/rendering-dynamic-blocks-using-astro","tutorials/1.getting-started/rendering-dynamic-blocks-using-astro","Learn how to render dynamic blocks using Astro.",{"title":1306,"path":1307,"stem":1308,"description":1309,"icon":14,"links":14},"Rendering Dynamic Blocks Using Next.js","/tutorials/getting-started/rendering-dynamic-blocks-using-next","tutorials/1.getting-started/rendering-dynamic-blocks-using-next","Learn how to render dynamic blocks using Next.js.",{"title":1311,"path":1312,"stem":1313,"description":1314,"icon":14,"links":14},"Rendering Dynamic Blocks Using Nuxt","/tutorials/getting-started/rendering-dynamic-blocks-using-nuxt","tutorials/1.getting-started/rendering-dynamic-blocks-using-nuxt","Learn how to render dynamic blocks using Nuxt.",{"title":1316,"path":1317,"stem":1318,"description":1319,"icon":14,"links":14},"Rendering Dynamic Blocks Using SvelteKit","/tutorials/getting-started/rendering-dynamic-blocks-using-sveltekit","tutorials/1.getting-started/rendering-dynamic-blocks-using-sveltekit","Learn how to render dynamic blocks using SvelteKit.",{"title":1321,"path":1322,"stem":1323,"description":1324,"icon":14,"links":14},"Set Up Live Preview with Next.js","/tutorials/getting-started/set-up-live-preview-with-next-js","tutorials/1.getting-started/set-up-live-preview-with-next-js","Learn how to confgure Live Preview with Next.js' draft mode.",{"title":1326,"path":1327,"stem":1328,"description":1329,"icon":14,"links":14},"Set Up Live Preview with Nuxt","/tutorials/getting-started/set-up-live-preview-with-nuxt","tutorials/1.getting-started/set-up-live-preview-with-nuxt","Learn how to create a Nuxt preview plugin to configure Live Preview.",{"title":1331,"path":1332,"stem":1333,"description":1334,"icon":14,"links":14},"Submit Forms Using Directus and Next.js","/tutorials/getting-started/submit-forms-using-directus-and-nextjs","tutorials/1.getting-started/submit-forms-using-directus-and-nextjs","Learn how to submit forms using Directus and Next.js.",{"title":1336,"path":1337,"stem":1338,"description":1339,"icon":14,"links":14},"Submit Forms Using Directus and Nuxt","/tutorials/getting-started/submit-forms-using-directus-and-nuxt","tutorials/1.getting-started/submit-forms-using-directus-and-nuxt","Learn how to submit forms using Directus and Nuxt.",{"title":1341,"path":1342,"stem":1343,"description":1344,"icon":14,"links":14},"Submit Forms Using Directus and SvelteKit","/tutorials/getting-started/submit-forms-using-directus-and-sveltekit","tutorials/1.getting-started/submit-forms-using-directus-and-sveltekit","Learn how to submit forms using Directus and SvelteKit.",{"title":1346,"path":1347,"stem":1348,"description":1349,"icon":14,"links":14},"Using Authentication in Astro","/tutorials/getting-started/using-authentication-in-astro","tutorials/1.getting-started/using-authentication-in-astro","Learn how to setup Directus authentication with Astro.",{"title":1351,"path":1352,"stem":1353,"description":1354,"icon":14,"links":14},"Using Authentication in Next.js","/tutorials/getting-started/using-authentication-in-next-js","tutorials/1.getting-started/using-authentication-in-next-js","Learn how to setup Directus authentication with Next.js.",{"title":1356,"path":1357,"stem":1358,"description":1359,"icon":14,"links":14},"Using Authentication in Nuxt","/tutorials/getting-started/using-authentication-in-nuxt","tutorials/1.getting-started/using-authentication-in-nuxt","Learn how to setup Directus authentication with Nuxt.",{"title":1361,"path":1362,"stem":1363,"description":1364,"icon":14,"links":14},"Using Authentication in React","/tutorials/getting-started/using-authentication-in-react","tutorials/1.getting-started/using-authentication-in-react","Learn how to setup Directus authentication with React.",{"title":1366,"path":1367,"stem":1368,"description":1369,"icon":14,"links":14},"Using Authentication in SvelteKit","/tutorials/getting-started/using-authentication-in-sveltekit","tutorials/1.getting-started/using-authentication-in-sveltekit","Learn how to setup Directus authentication with SvelteKit.",{"title":145,"path":1371,"stem":1372,"children":1373,"description":24,"icon":14,"links":14},"/tutorials/projects","tutorials/2.projects/index",[1374,1375,1380,1385,1390,1395,1400,1405,1410,1415,1420,1425,1430,1435,1440,1445,1450,1455,1460,1465,1470,1475,1480,1485,1490,1495,1500,1505,1510,1515,1520,1525],{"title":145,"path":1371,"stem":1372,"description":24,"icon":14,"links":14},{"title":1376,"path":1377,"stem":1378,"description":1379,"icon":14,"links":14},"Build a Multi-User Chat with JavaScript and Directus Realtime","/tutorials/projects/build-a-multi-user-chat-with-javascript-and-directus-realtime","tutorials/2.projects/build-a-multi-user-chat-with-javascript-and-directus-realtime","Learn how to send and receive data over a realtime connection with JavaScript.",{"title":1381,"path":1382,"stem":1383,"description":1384,"icon":14,"links":14},"Build a Multi-User Chat with React and Directus Realtime","/tutorials/projects/build-a-multi-user-chat-with-react-and-directus-realtime","tutorials/2.projects/build-a-multi-user-chat-with-react-and-directus-realtime","Learn how to send and receive data over a realtime connection in React applications.",{"title":1386,"path":1387,"stem":1388,"description":1389,"icon":14,"links":14},"Build a Multi-User Chat with Vue.js and Directus Realtime","/tutorials/projects/build-a-multi-user-chat-with-vue-js-and-directus-realtime","tutorials/2.projects/build-a-multi-user-chat-with-vue-js-and-directus-realtime","Learn how to send and receive data over a realtime connection in a Vue.js application.",{"title":1391,"path":1392,"stem":1393,"description":1394,"icon":14,"links":14},"Build a Notebook Chrome Extension with Directus Auth","/tutorials/projects/build-a-notebook-chrome-extension-with-directus-auth","tutorials/2.projects/build-a-notebook-chrome-extension-with-directus-auth","Learn to build and integrate a Chrome Extension with Directus Auth.",{"title":1396,"path":1397,"stem":1398,"description":1399,"icon":14,"links":14},"Build a Realtime Chat App with Directus and Astro","/tutorials/projects/build-a-realtime-chat-app-using-directus-and-astro","tutorials/2.projects/build-a-realtime-chat-app-using-directus-and-astro","Learn how to setup Directus realtime with Astro.",{"title":1401,"path":1402,"stem":1403,"description":1404,"icon":14,"links":14},"Build a Realtime Chat App with Directus and Nuxt","/tutorials/projects/build-a-realtime-chat-app-using-directus-and-nuxt","tutorials/2.projects/build-a-realtime-chat-app-using-directus-and-nuxt","Learn how to setup Directus realtime with Nuxt.",{"title":1406,"path":1407,"stem":1408,"description":1409,"icon":14,"links":14},"Build a Realtime Chat App with Directus and Next.js","/tutorials/projects/build-a-realtime-chat-app-with-directus-and-next","tutorials/2.projects/build-a-realtime-chat-app-with-directus-and-next","Learn how to setup Directus realtime with Next.js.",{"title":1411,"path":1412,"stem":1413,"description":1414,"icon":14,"links":14},"Build a Realtime Chat App with Directus and SvelteKit","/tutorials/projects/build-a-realtime-chat-app-with-directus-and-sveltekit","tutorials/2.projects/build-a-realtime-chat-app-with-directus-and-sveltekit","Learn how to setup Directus realtime with SvelteKit.",{"title":1416,"path":1417,"stem":1418,"description":1419,"icon":14,"links":14},"Build a Testimonial Widget with SvelteKit and Directus","/tutorials/projects/build-a-testimonial-widget-with-sveltekit-and-directus","tutorials/2.projects/build-a-testimonial-widget-with-sveltekit-and-directus","Learn how to set up a testimonial widget using SvelteKit and Directus.",{"title":1421,"path":1422,"stem":1423,"description":1424,"icon":14,"links":14},"Build a User Feedback Widget with Vue.js","/tutorials/projects/build-a-user-feedback-widget-with-vue-js","tutorials/2.projects/build-a-user-feedback-widget-with-vue-js-","Learn how we built our docs feedback widget with Directus.",{"title":1426,"path":1427,"stem":1428,"description":1429,"icon":14,"links":14},"Build a Video Streaming App with SvelteKit and Directus","/tutorials/projects/build-a-video-streaming-app-with-sveltekit-and-directus","tutorials/2.projects/build-a-video-streaming-app-with-sveltekit-and-directus","Learn how to store and retrieve video metadata, and then build a streaming application.",{"title":1431,"path":1432,"stem":1433,"description":1434,"icon":14,"links":14},"Build an Ecommerce Platform with Next.js, Stripe, and Directus Automate","/tutorials/projects/build-an-ecommerce-platform-with-next-js-stripe-and-directus-automate","tutorials/2.projects/build-an-ecommerce-platform-with-next-js-stripe-and-directus-automate","Learn to integrate Stripe with Directus Automate to build an e-commerce website.",{"title":1436,"path":1437,"stem":1438,"description":1439,"icon":14,"links":14},"Build an Hotel Booking Platform with Next.js, Stripe, and Directus Automate","/tutorials/projects/build-an-hotel-booking-platform-with-next-js-stripe-and-directus-automate","tutorials/2.projects/build-an-hotel-booking-platform-with-next-js-stripe-and-directus-automate","Learn to build a hotel booking site with dynamic availability and payments via Stripe.",{"title":1441,"path":1442,"stem":1443,"description":1444,"icon":14,"links":14},"Build Directus Garden - A Passive Collaborative Event Booth Demo","/tutorials/projects/build-directus-garden-a-passive-collaborative-event-booth-demo","tutorials/2.projects/build-directus-garden-a-passive-collaborative-event-booth-demo","Learn how we built our engagement platform for live in-person events with P5.js.",{"title":1446,"path":1447,"stem":1448,"description":1449,"icon":14,"links":14},"Build Forms Dynamically using Directus and Astro","/tutorials/projects/build-forms-dynamically-using-directus-and-astro","tutorials/2.projects/build-forms-dynamically-using-directus-and-astro","Learn how to setup Directus fields with Astro.",{"title":1451,"path":1452,"stem":1453,"description":1454,"icon":14,"links":14},"Build Forms Dynamically using Directus and Next.js","/tutorials/projects/build-forms-dynamically-using-directus-and-next","tutorials/2.projects/build-forms-dynamically-using-directus-and-next","Learn how to setup Directus fields with Next.js.",{"title":1456,"path":1457,"stem":1458,"description":1459,"icon":14,"links":14},"Build Forms Dynamically using Directus and Nuxt","/tutorials/projects/build-forms-dynamically-using-directus-and-nuxt","tutorials/2.projects/build-forms-dynamically-using-directus-and-nuxt","Learn how to setup Directus fields with Nuxt.",{"title":1461,"path":1462,"stem":1463,"description":1464,"icon":14,"links":14},"Build Forms Dynamically using Directus and SvelteKit","/tutorials/projects/build-forms-dynamically-using-directus-and-sveltekit","tutorials/2.projects/build-forms-dynamically-using-directus-and-sveltekit","Learn how to setup Directus fields with SvelteKit.",{"title":1466,"path":1467,"stem":1468,"description":1469,"icon":14,"links":14},"Build the Leap Week Registration and Referral System","/tutorials/projects/build-the-leap-week-registration-and-referral-system","tutorials/2.projects/build-the-leap-week-registration-and-referral-system-","Learn how we built our referral-based ticketing and raffle system with AI-generated rabbitars.",{"title":1471,"path":1472,"stem":1473,"description":1474,"icon":14,"links":14},"Building AIVenture - An AI-Powered Game with Directus","/tutorials/projects/building-ai-venture-an-ai-powered-game-with-directus","tutorials/2.projects/building-ai-venture-an-ai-powered-game-with-directus","Learn the advanced techniques used with Directus Automate to build a game.",{"title":1476,"path":1477,"stem":1478,"description":1479,"icon":14,"links":14},"Create a CMS using Directus and Astro","/tutorials/projects/create-a-cms-using-directus-and-astro","tutorials/2.projects/create-a-cms-using-directus-and-astro","Learn how to create a CMS using Directus and Astro.",{"title":1481,"path":1482,"stem":1483,"description":1484,"icon":14,"links":14},"Create a CMS using Directus and Next.js","/tutorials/projects/create-a-cms-using-directus-and-nextjs","tutorials/2.projects/create-a-cms-using-directus-and-nextjs","Learn how to create a CMS using Directus and Next.js.",{"title":1486,"path":1487,"stem":1488,"description":1489,"icon":14,"links":14},"Create a CMS using Directus and Nuxt","/tutorials/projects/create-a-cms-using-directus-and-nuxt","tutorials/2.projects/create-a-cms-using-directus-and-nuxt","Learn how to create a CMS using Directus and Nuxt.",{"title":1491,"path":1492,"stem":1493,"description":1494,"icon":14,"links":14},"Create a CMS using Directus and SvelteKit","/tutorials/projects/create-a-cms-using-directus-and-sveltekit","tutorials/2.projects/create-a-cms-using-directus-and-sveltekit","Learn how to create a CMS using Directus and SvelteKit.",{"title":1496,"path":1497,"stem":1498,"description":1499,"icon":14,"links":14},"Create Dynamic Pages for a CMS using Directus and Astro","/tutorials/projects/create-dynamic-pages-for-a-cms-using-directus-and-astro","tutorials/2.projects/create-dynamic-pages-for-a-cms-using-directus-and-astro","Learn how to create dynamic pages you can use in your CMS using Directus and Astro.",{"title":1501,"path":1502,"stem":1503,"description":1504,"icon":14,"links":14},"Create Dynamic Pages for a CMS using Directus and Next.js","/tutorials/projects/create-dynamic-pages-for-a-cms-using-directus-and-nextjs","tutorials/2.projects/create-dynamic-pages-for-a-cms-using-directus-and-nextjs","Learn how to create dynamic pages you can use in your CMS using Directus and Next.js.",{"title":1506,"path":1507,"stem":1508,"description":1509,"icon":14,"links":14},"Create Dynamic Pages for a CMS using Directus and Nuxt","/tutorials/projects/create-dynamic-pages-for-a-cms-using-directus-and-nuxt","tutorials/2.projects/create-dynamic-pages-for-a-cms-using-directus-and-nuxt","Learn how to create dynamic pages you can use in your CMS using Directus and Nuxt.",{"title":1511,"path":1512,"stem":1513,"description":1514,"icon":14,"links":14},"Create Dynamic Pages for a CMS using Directus and SvelteKit","/tutorials/projects/create-dynamic-pages-for-a-cms-using-directus-and-sveltekit","tutorials/2.projects/create-dynamic-pages-for-a-cms-using-directus-and-sveltekit","Learn how to create dynamic pages you can use in your CMS using Directus and SvelteKit.",{"title":1516,"path":1517,"stem":1518,"description":1519,"icon":14,"links":14},"How I Built an AI Open Source Santa Roast App with Directus and Nuxt","/tutorials/projects/how-i-built-an-ai-open-source-santa-roast-app-with-directus-and-nuxt","tutorials/2.projects/how-i-built-an-ai-open-source-santa-roast-app-with-directus-and-nuxt","Bryant breaks down how he built an AI-powered app that roasts developers based on their GitHub contributions.",{"title":1521,"path":1522,"stem":1523,"description":1524,"icon":14,"links":14},"Integrate Directus with ESP32 Hardware Sensors","/tutorials/projects/integrate-directus-with-esp-32-hardware-sensors","tutorials/2.projects/integrate-directus-with-esp-32-hardware-sensors","Learn how to integrate Directus with IoT systems by reading and publishing sensor data.",{"title":1526,"path":1527,"stem":1528,"description":1529,"icon":14,"links":14},"Use Directus as a Baby Health Tracker with Owlet and OpsGenie","/tutorials/projects/use-directus-as-a-baby-health-tracker-with-owlet-and-ops-genie","tutorials/2.projects/use-directus-as-a-baby-health-tracker-with-owlet-and-ops-genie","Learn how to integrate Directus with hardware sensors and incident repsonse systems.",{"title":1531,"path":1532,"stem":1533,"children":1534,"description":24,"icon":14,"links":14},"Tips & Tricks","/tutorials/tips-and-tricks","tutorials/3.tips-and-tricks/index",[1535,1536,1541,1546,1551,1556,1561,1566,1571],{"title":1531,"path":1532,"stem":1533,"description":24,"icon":14,"links":14},{"title":1537,"path":1538,"stem":1539,"description":1540,"icon":14,"links":14},"Advanced Types with the Directus SDK","/tutorials/tips-and-tricks/advanced-types-with-the-directus-sdk","tutorials/3.tips-and-tricks/advanced-types-with-the-directus-sdk","Learn how to more-easily work with types and the Directus SDK.",{"title":1542,"path":1543,"stem":1544,"description":1545,"icon":14,"links":14},"Build a Monitoring Pipeline For Flows And Extensions","/tutorials/tips-and-tricks/build-a-monitoring-pipeline-for-flows-and-extensions","tutorials/3.tips-and-tricks/build-a-monitoring-pipeline-for-flows-and-extensions-","Learn how to set up complex pipelines to monitor automations and extensions.",{"title":1547,"path":1548,"stem":1549,"description":1550,"icon":14,"links":14},"Configure Okta as a Single Sign-On Provider","/tutorials/tips-and-tricks/configure-okta-as-a-single-sign-on-provider","tutorials/3.tips-and-tricks/configure-okta-as-a-single-sign-on-provider","Learn how to set up Okta SSO with the SAML authentication mechanism.",{"title":1552,"path":1553,"stem":1554,"description":1555,"icon":14,"links":14},"Implement Pagination and Infinite Scrolling in Next.js","/tutorials/tips-and-tricks/implement-pagination-and-infinite-scrolling-in-next-js","tutorials/3.tips-and-tricks/implement-pagination-and-infinite-scrolling-in-next-js-","Learn various techniques to load paginated data in your Next.js application.",{"title":1557,"path":1558,"stem":1559,"description":1560,"icon":14,"links":14},"Importing Files in Directus Automate","/tutorials/tips-and-tricks/importing-files-in-directus-automate","tutorials/3.tips-and-tricks/importing-files-in-directus-automate","Learn how to use the Request URL operation to import files in Directus Automate.",{"title":1562,"path":1563,"stem":1564,"description":1565,"icon":14,"links":14},"Preview Files in Live Preview with Google Docs Previews","/tutorials/tips-and-tricks/preview-files-in-live-preview-with-google-docs-previews","tutorials/3.tips-and-tricks/preview-files-in-live-preview-with-google-docs-previews","Learn how to use Google Gview to preview many file formats in Directus Editor.",{"title":1567,"path":1568,"stem":1569,"description":1570,"icon":14,"links":14},"Search Engine Optimization Best Practices","/tutorials/tips-and-tricks/search-engine-optimization-best-practices","tutorials/3.tips-and-tricks/search-engine-optimization-best-practices","Learn some best practices for enabling SEO in your projects using Directus.",{"title":1572,"path":1573,"stem":1574,"description":1575,"icon":14,"links":14},"Understanding Kubernetes","/tutorials/tips-and-tricks/understanding-kubernetes","tutorials/3.tips-and-tricks/understanding-kubernetes","Learn about key Kubernetes concepts and how they interact with each other.",{"title":1577,"path":1578,"stem":1579,"children":1580,"description":24,"icon":14,"links":14},"Migration","/tutorials/migration","tutorials/4.migration/index",[1581,1582,1587,1592,1597],{"title":1577,"path":1578,"stem":1579,"description":24,"icon":14,"links":14},{"title":1583,"path":1584,"stem":1585,"description":1586,"icon":14,"links":14},"Migrate from Notion to Directus","/tutorials/migration/migrate-from-notion-to-directus","tutorials/4.migration/migrate-from-notion-to-directus","Learn how to migrate data from Notion databases to Directus.",{"title":1588,"path":1589,"stem":1590,"description":1591,"icon":14,"links":14},"Migrate from Nuxt Content to Directus","/tutorials/migration/migrate-from-nuxt-content-to-directus","tutorials/4.migration/migrate-from-nuxt-content-to-directus","Learn how to move from a flat-file CMS to Directus.",{"title":1593,"path":1594,"stem":1595,"description":1596,"icon":14,"links":14},"Migrate from WordPress to Directus","/tutorials/migration/migrate-from-wordpress-to-directus","tutorials/4.migration/migrate-from-wordpress-to-directus","Learn how to migrate posts and images to Directus, with tips on plugins.",{"title":1598,"path":1599,"stem":1600,"description":1601,"icon":14,"links":14},"Promoting Changes Between Environments in Directus","/tutorials/migration/promoting-changes-between-environments-in-directus","tutorials/4.migration/promoting-changes-between-environments-in-directus","Learn the options to migrate schema and data between Directus projects.",{"title":372,"path":1603,"stem":1604,"children":1605,"description":1607,"icon":14,"links":14},"/tutorials/extensions","tutorials/5.extensions/index",[1606,1608,1613,1618,1623,1628,1633,1638,1643,1650,1657,1664,1669,1674,1679,1684,1689,1694,1699,1704,1709,1714],{"title":372,"path":1603,"stem":1604,"description":1607,"icon":14,"links":14},"All about extensions",{"title":1609,"path":1610,"stem":1611,"description":1612,"icon":14,"links":14},"Check Permissions in a Custom Endpoint","/tutorials/extensions/check-permissions-in-a-custom-endpoint","tutorials/5.extensions/check-permissions-in-a-custom-endpoint","Learn how to use internal Directus permissions when creating a custom endpoint.",{"title":1614,"path":1615,"stem":1616,"description":1617,"icon":14,"links":14},"Create Collection Items in Custom Panels","/tutorials/extensions/create-collection-items-in-custom-panels","tutorials/5.extensions/create-collection-items-in-custom-panels","Learn how to use built-in interfaces and composables to create new collections.",{"title":1619,"path":1620,"stem":1621,"description":1622,"icon":14,"links":14},"Create New Customers in Stripe in a Custom Hook","/tutorials/extensions/create-new-customers-in-stripe-in-a-custom-hook","tutorials/5.extensions/create-new-customers-in-stripe-in-a-custom-hook","Learn how to use the Stripe SDK to create data when actions occur in Directus.",{"title":1624,"path":1625,"stem":1626,"description":1627,"icon":14,"links":14},"Display External API Data From Vonage In Custom Panels","/tutorials/extensions/display-external-api-data-from-vonage-in-custom-panels","tutorials/5.extensions/display-external-api-data-from-vonage-in-custom-panels","Learn how to display records from external systems in Directus Insights.",{"title":1629,"path":1630,"stem":1631,"description":1632,"icon":14,"links":14},"Display External Weather API Data In Custom Panels","/tutorials/extensions/display-external-weather-api-data-in-custom-panels","tutorials/5.extensions/display-external-weather-api-data-in-custom-panels","Learn how to display external data in panels with a bundle and endpoint.",{"title":1634,"path":1635,"stem":1636,"description":1637,"icon":14,"links":14},"Format Dates in a Custom Display Extension","/tutorials/extensions/format-dates-in-a-custom-display-extension","tutorials/5.extensions/format-dates-in-a-custom-display-extension","Learn how to build a custom display to format data in Directus.",{"title":1639,"path":1640,"stem":1641,"description":1642,"icon":14,"links":14},"Implement Navigation in Multipage Custom Modules","/tutorials/extensions/implement-navigation-in-multipage-custom-modules","tutorials/5.extensions/implement-navigation-in-multipage-custom-modules","Learn how to navigate between multiple pages in module extensions.",{"title":1644,"path":1645,"stem":1646,"children":1647,"description":1649,"icon":14,"links":14},"Integrate Algolia Indexing with Custom Hooks","/tutorials/extensions/integrate-algolia-indexing-with-custom-hooks","tutorials/5.extensions/integrate-algolia-indexing-with-custom-hooks",[1648],{"title":1644,"path":1645,"stem":1646,"description":1649,"icon":14,"links":14},"Learn how to maintain an Algolia index when data is created, updated, and deleted.",{"title":1651,"path":1652,"stem":1653,"children":1654,"description":1656,"icon":14,"links":14},"Integrate Elasticsearch Indexing with Custom Hooks","/tutorials/extensions/integrate-elasticsearch-indexing-with-custom-hooks","tutorials/5.extensions/integrate-elasticsearch-indexing-with-custom-hooks",[1655],{"title":1651,"path":1652,"stem":1653,"description":1656,"icon":14,"links":14},"Learn how to maintain an Elasticsearch index when data is created, updated, and deleted.",{"title":1658,"path":1659,"stem":1660,"children":1661,"description":1663,"icon":14,"links":14},"Integrate Meilisearch Indexing with Custom Hooks","/tutorials/extensions/integrate-meilisearch-indexing-with-custom-hooks","tutorials/5.extensions/integrate-meilisearch-indexing-with-custom-hooks",[1662],{"title":1658,"path":1659,"stem":1660,"description":1663,"icon":14,"links":14},"Learn how to maintain an Meilisearch index when data is created, updated, and deleted.",{"title":1665,"path":1666,"stem":1667,"description":1668,"icon":14,"links":14},"Monitor and Error Track with Sentry in Custom Hooks","/tutorials/extensions/monitor-and-error-track-with-sentry-in-custom-hooks","tutorials/5.extensions/monitor-and-error-track-with-sentry-in-custom-hooks","Learn how to integrate Sentry error tracking in both your API and Data Studio.",{"title":1670,"path":1671,"stem":1672,"description":1673,"icon":14,"links":14},"Proxy an External API in a Custom Endpoint Extension","/tutorials/extensions/proxy-an-external-api-in-a-custom-endpoint-extension","tutorials/5.extensions/proxy-an-external-api-in-a-custom-endpoint-extension","Learn how to make external APIs available via Directus in a custom endpoint.",{"title":1675,"path":1676,"stem":1677,"description":1678,"icon":14,"links":14},"Read Collection Data in Custom Layouts","/tutorials/extensions/read-collection-data-in-custom-layouts","tutorials/5.extensions/read-collection-data-in-custom-layouts","Learn how to build your first layout with data from a collection.",{"title":1680,"path":1681,"stem":1682,"description":1683,"icon":14,"links":14},"Send SMS Messages with Twilio in Custom Operations","/tutorials/extensions/send-sms-messages-with-twilio-in-custom-operations","tutorials/5.extensions/send-sms-messages-with-twilio-in-custom-operations","Learn how to build a custom operation that uses the Twilio SDK.",{"title":1685,"path":1686,"stem":1687,"description":1688,"icon":14,"links":14},"Send SMS Messages with Twilio in Custom Panels","/tutorials/extensions/send-sms-messages-with-twilio-in-custom-panels","tutorials/5.extensions/send-sms-messages-with-twilio-in-custom-panels","Learn how to build a form inside a panel extension and use external APIs.",{"title":1690,"path":1691,"stem":1692,"description":1693,"icon":14,"links":14},"Summarize Relational Items in a Custom Display Extension","/tutorials/extensions/summarize-relational-items-in-a-custom-display-extension","tutorials/5.extensions/summarize-relational-items-in-a-custom-display-extension","Learn how to work with relational data in display extensions.",{"title":1695,"path":1696,"stem":1697,"description":1698,"icon":14,"links":14},"Understand Available Slots in Custom Modules","/tutorials/extensions/understand-available-slots-in-custom-modules","tutorials/5.extensions/understand-available-slots-in-custom-modules","Learn about all of the slots available in your custom modules.",{"title":1700,"path":1701,"stem":1702,"description":1703,"icon":14,"links":14},"Use Dynamic Values in Custom Email Templates","/tutorials/extensions/use-dynamic-values-in-custom-email-templates","tutorials/5.extensions/use-dynamic-values-in-custom-email-templates","Learn how to inject dynamic data into liquid templates.",{"title":1705,"path":1706,"stem":1707,"description":1708,"icon":14,"links":14},"Use npm Packages in Custom Operations","/tutorials/extensions/use-npm-packages-in-custom-operations","tutorials/5.extensions/use-npm-packages-in-custom-operations","Learn how to expose an npm package as an operation in Directus Automate.",{"title":1710,"path":1711,"stem":1712,"description":1713,"icon":14,"links":14},"Validate Phone Numbers with Twilio in a Custom Hook","/tutorials/extensions/validate-phone-numbers-with-twilio-in-a-custom-hook","tutorials/5.extensions/validate-phone-numbers-with-twilio-in-a-custom-hook","Learn how to prevent an item from saving if it has an invalid phone number.",{"title":1715,"path":1716,"stem":1717,"description":1718,"icon":14,"links":14},"Validating Third-Party JWTs in Directus (with Okta)","/tutorials/extensions/validating-third-party-jwts-in-directus","tutorials/5.extensions/validating-third-party-jwts-in-directus","Learn how to translate third part JWT's to Directus accountability",{"title":1114,"path":1720,"stem":1721,"children":1722,"description":24,"icon":14,"links":14},"/tutorials/self-hosting","tutorials/6.self-hosting/index",[1723,1724,1729,1734,1739,1744],{"title":1114,"path":1720,"stem":1721,"description":24,"icon":14,"links":14},{"title":1725,"path":1726,"stem":1727,"description":1728,"icon":14,"links":14},"Deploy Directus to an Ubuntu Server","/tutorials/self-hosting/deploy-directus-to-an-ubuntu-server","tutorials/6.self-hosting/deploy-directus-to-an-ubuntu-server","Learn how to deploy Directus on a Docker container on an Ubuntu server.",{"title":1730,"path":1731,"stem":1732,"description":1733,"icon":14,"links":14},"Deploy Directus to AWS EC2","/tutorials/self-hosting/deploy-directus-to-aws-ec2","tutorials/6.self-hosting/deploy-directus-to-aws-ec2","Learn how to deploy a Directus to AWS EC2, with a RDS database and a S3 storage bucket.",{"title":1735,"path":1736,"stem":1737,"description":1738,"icon":14,"links":14},"Deploy Directus to Azure Web Apps","/tutorials/self-hosting/deploy-directus-to-azure-web-apps","tutorials/6.self-hosting/deploy-directus-to-azure-web-apps","Learn how to deploy Directus on a Docker container on Azure.",{"title":1740,"path":1741,"stem":1742,"description":1743,"icon":14,"links":14},"Deploy Directus to Digital Ocean","/tutorials/self-hosting/deploy-directus-to-digital-ocean","tutorials/6.self-hosting/deploy-directus-to-digital-ocean","Learn how to deploy Directus on the Digital Ocean App Platform.",{"title":1745,"path":1746,"stem":1747,"description":1748,"icon":14,"links":14},"Deploy Directus to Google Cloud Platform","/tutorials/self-hosting/deploy-directus-to-google-cloud-platform","tutorials/6.self-hosting/deploy-directus-to-google-cloud-platform","Learn how to deploy Directus on GCP with a Cloud SQL database and Cloud Storage Bucket.",{"title":1750,"path":1751,"stem":1752,"children":1753,"description":24,"icon":14,"links":14},"Workflows","/tutorials/workflows","tutorials/7.workflows/index",[1754,1755,1760,1765,1770,1775,1780,1785,1790,1795,1800,1805,1810,1815,1820],{"title":1750,"path":1751,"stem":1752,"description":24,"icon":14,"links":14},{"title":1756,"path":1757,"stem":1758,"description":1759,"icon":14,"links":14},"Build Content Approval Workflows with Custom Permissions","/tutorials/workflows/build-content-approval-workflows-with-custom-permissions","tutorials/7.workflows/build-content-approval-workflows-with-custom-permissions","Learn how to configure roles and permissions for complex automations.",{"title":1761,"path":1762,"stem":1763,"description":1764,"icon":14,"links":14},"Combine Live Preview and Content Versioning with Next.js","/tutorials/workflows/combine-live-preview-and-content-versioning-with-next-js","tutorials/7.workflows/combine-live-preview-and-content-versioning-with-next-js","Learn how to set up Live Preview with different content versions in your Next.js application.",{"title":1766,"path":1767,"stem":1768,"description":1769,"icon":14,"links":14},"Create GitHub Issues with Directus Automate","/tutorials/workflows/create-github-issues-with-directus-automate","tutorials/7.workflows/create-github-issues-with-directus-automate","Learn how to integrate GitHub with Directus Automate to create new issues.",{"title":1771,"path":1772,"stem":1773,"description":1774,"icon":14,"links":14},"Detect High-Risk Phone Numbers with Vonage and Directus Automate","/tutorials/workflows/detect-high-risk-phone-numbers-with-vonage-and-directus-automate","tutorials/7.workflows/detect-high-risk-phone-numbers-with-vonage-and-directus-automate","Learn how to integrate Vonage's Number Insights API with Directus Automate to validate numbers.",{"title":1776,"path":1777,"stem":1778,"description":1779,"icon":14,"links":14},"Enrich User Data with Clearbit and Directus Automate","/tutorials/workflows/enrich-user-data-with-clearbit-and-directus-automate","tutorials/7.workflows/enrich-user-data-with-clearbit-and-directus-automate","Learn how to integrate Clearbit data enrichment with Directus Automate.",{"title":1781,"path":1782,"stem":1783,"description":1784,"icon":14,"links":14},"Generate Images with DALL•E and Directus Automate","/tutorials/workflows/generate-images-with-dall-e-and-directus-automate","tutorials/7.workflows/generate-images-with-dall-e-and-directus-automate","Learn how to integrate OpenAI's Dall•E models with Directus Automate.",{"title":1786,"path":1787,"stem":1788,"description":1789,"icon":14,"links":14},"Generate Social Posts with GPT-4 and Directus Automate","/tutorials/workflows/generate-social-posts-with-gpt-4-and-directus-automate","tutorials/7.workflows/generate-social-posts-with-gpt-4-and-directus-automate","Learn how to integrate OpenAI's GPT-4 model with Directus Automate.",{"title":1791,"path":1792,"stem":1793,"description":1794,"icon":14,"links":14},"Generate Transcripts with Deepgram and Directus Automate","/tutorials/workflows/generate-transcripts-with-deepgram-and-directus-automate","tutorials/7.workflows/generate-transcripts-with-deepgram-and-directus-automate","Learn how to integrate Deepgram's Speech-to-Text API with Directus Automate.",{"title":1796,"path":1797,"stem":1798,"description":1799,"icon":14,"links":14},"Integrating Multilingual Content with Directus and Crowdin","/tutorials/workflows/integrating-multilingual-content-with-directus-and-crowdin","tutorials/7.workflows/integrating-multilingual-content-with-directus-and-crowdin","Learn how to localize content in Directus using Crowdin's connector with Directus.",{"title":1801,"path":1802,"stem":1803,"description":1804,"icon":14,"links":14},"Invincible AI content workflows with Inngest and Directus","/tutorials/workflows/invincible-ai-content-workflows-with-inngest-and-directus","tutorials/7.workflows/invincible-ai-content-workflows-with-inngest-and-directus","Learn how to configure integration Directus and Inngest to build durable workflows for any scale.",{"title":1806,"path":1807,"stem":1808,"description":1809,"icon":14,"links":14},"Schedule Future Content with Directus Automate","/tutorials/workflows/schedule-future-content-with-directus-automate","tutorials/7.workflows/schedule-future-content-with-directus-automate","Learn how to set content to be scheduled on a future date with Directs Automate.",{"title":1811,"path":1812,"stem":1813,"description":1814,"icon":14,"links":14},"Tag Images with Clarifai and Directus Automate","/tutorials/workflows/tag-images-with-clarifai-and-directus-automate","tutorials/7.workflows/tag-images-with-clarifai-and-directus-automate","Learn how to integrate Clarifai's image recognition APIs with Directus Automate.",{"title":1816,"path":1817,"stem":1818,"description":1819,"icon":14,"links":14},"Trigger Netlify Site Builds with Directus Automate","/tutorials/workflows/trigger-netlify-site-builds-with-directus-automate","tutorials/7.workflows/trigger-netlify-site-builds-with-directus-automate","Learn how to trigger new Netlify website builds through Directus Automate.",{"title":1821,"path":1822,"stem":1823,"description":1824,"icon":14,"links":14},"Trigger Vercel Site Builds with Directus Automate","/tutorials/workflows/trigger-vercel-site-builds-with-directus-automate","tutorials/7.workflows/trigger-vercel-site-builds-with-directus-automate","Learn how to trigger new Vercel website builds through Directus Automate.",{"id":1826,"icon":1827,"content":1828,"link":1829},"812bf73d-ebfb-4246-9538-937a09a0c795","connected_tv","Learn more about our native MCP","https://directus.io/mcp",{"id":1831,"title":1366,"authors":1832,"body":1836,"description":1369,"extension":9053,"headline":14,"icon":14,"links":14,"meta":9054,"navigation":2698,"path":1367,"rawbody":9056,"seo":9057,"stem":1368,"technologies":9058,"__hash__":9060},"content/tutorials/1.getting-started/using-authentication-in-sveltekit.md",[1833],{"name":1834,"title":1835},"Temitope Oyedelde","Guest Author",{"type":1837,"value":1838,"toc":9026},"minimark",[1839,1843,1847,1851,1854,1875,1879,1886,1894,1932,1937,1948,1968,1975,1979,1991,2028,2062,2090,2117,2124,2127,2131,2134,2141,2147,2150,2154,2157,2180,2183,2531,2538,2551,2554,2557,2571,2575,2586,2663,2666,2670,2684,3308,3315,3319,3330,3897,3901,3908,3993,3997,4002,4078,4082,4085,4092,4245,4252,4256,4263,4270,4562,4565,4569,4582,4585,4941,4944,4948,4962,6246,6253,6257,6260,6269,7151,7154,7173,7177,7180,7193,7743,7749,7764,8607,8622,8626,8631,8634,8743,8746,8750,8757,8945,8949,8952,8966,8977,8984,8990,8997,9003,9006,9012,9015,9019,9022],[1840,1841,130],"h2",{"id":1842},"introduction",[1844,1845,1846],"p",{},"Authentication is a critical part of any modern web application. It ensures that users can securely access their data and perform authorized actions. In this tutorial, you will learn how to implement authentication in your SvelteKit application using Directus' built-in authentication system.",[1840,1848,1850],{"id":1849},"before-you-start","Before You Start",[1844,1852,1853],{},"Before you proceed, you will need the following:",[1855,1856,1857,1869,1872],"ul",{},[1858,1859,1860,1861,1868],"li",{},"A ",[1862,1863,1867],"a",{"href":1864,"rel":1865},"https://directus.io/docs/",[1866],"nofollow","Directus project"," with admin access.",[1858,1870,1871],{},"Fundamental understanding of Svelte.",[1858,1873,1874],{},"Optional but recommended: Familiarity with data modeling in Directus.",[1840,1876,1878],{"id":1877},"set-up-your-directus-project","Set Up Your Directus Project",[1844,1880,1881,1882,1885],{},"In this tutorial, Docker will be used for this setup. To get started, follow the ",[1862,1883,1884],{"href":443},"Docker setup instructions",".",[1844,1887,1888,1889,1893],{},"You also need to make sure to configure CORS. Update your ",[1890,1891,1892],"code",{},"docker-compose.yml"," file as follows:",[1895,1896,1900],"pre",{"className":1897,"code":1898,"language":1899,"meta":24,"style":24},"language-bash shiki shiki-themes github-light github-light github-dark","   CORS_ENABLED: \"true\"\n   CORS_ORIGIN: \"http://localhost:5173\"\n   CORS_CREDENTIALS: \"true\"\n","bash",[1890,1901,1902,1915,1924],{"__ignoreMap":24},[1903,1904,1907,1911],"span",{"class":1905,"line":1906},"line",1,[1903,1908,1910],{"class":1909},"snPdu","   CORS_ENABLED:",[1903,1912,1914],{"class":1913},"sIIMD"," \"true\"\n",[1903,1916,1918,1921],{"class":1905,"line":1917},2,[1903,1919,1920],{"class":1909},"   CORS_ORIGIN:",[1903,1922,1923],{"class":1913}," \"http://localhost:5173\"\n",[1903,1925,1927,1930],{"class":1905,"line":1926},3,[1903,1928,1929],{"class":1909},"   CORS_CREDENTIALS:",[1903,1931,1914],{"class":1913},[1933,1934,1936],"h3",{"id":1935},"create-a-collection","Create a Collection",[1844,1938,1939,1940,1943,1944,1947],{},"Create a new collection called ",[1890,1941,1942],{},"posts"," with the ",[1890,1945,1946],{},"user_created"," optional field and the following custom fields:",[1855,1949,1950,1956,1962],{},[1858,1951,1952,1955],{},[1890,1953,1954],{},"title"," (Type: String)",[1858,1957,1958,1961],{},[1890,1959,1960],{},"content"," (Type: Markdown)",[1858,1963,1964,1967],{},[1890,1965,1966],{},"author"," (Type: User)",[1844,1969,1970],{},[1971,1972],"img",{"alt":1973,"src":1974},"Post Collection","/img/post_collection.png",[1840,1976,1978],{"id":1977},"configure-roles-policies-and-permissions","Configure Roles, Policies, and Permissions",[1844,1980,1981,1982,1985,1986,1990],{},"Create a new role called ",[1890,1983,1984],{},"Authenticated User"," in the ",[1987,1988,1989],"strong",{},"User Roles"," section. In this role, you will create a number of policies.",[1844,1992,1993,1994,1997,1998,2000,2001,2004,2005,2008,2009,2012,2013,2016,2017,2020,2021,2023,2024,2027],{},"First, create a policy and name it ",[1890,1995,1996],{},"Can Read and Create Posts",". Select the ",[1987,1999,1942],{}," collection to set some permissions. Set the ",[1987,2002,2003],{},"Read"," permission to ",[1987,2006,2007],{},"Allow Access"," in the options. You also need to set ",[1987,2010,2011],{},"Create"," permission to custom by clicking ",[1987,2014,2015],{},"Use Custom"," in the options, and in the  ",[1987,2018,2019],{},"Field Permissions",", uncheck ",[1890,2022,1966],{}," so the user cannot set any value. Then, in the ",[1987,2025,2026],{},"Field Presets",", add the following value to set the value automatically:",[1895,2029,2031],{"className":1897,"code":2030,"language":1899,"meta":24,"style":24},"{\n    \"author\": \"$CURRENT_USER\"\n}\n",[1890,2032,2033,2039,2057],{"__ignoreMap":24},[1903,2034,2035],{"class":1905,"line":1906},[1903,2036,2038],{"class":2037},"sxrX7","{\n",[1903,2040,2041,2044,2048,2051,2054],{"class":1905,"line":1917},[1903,2042,2043],{"class":1909},"    \"author\"",[1903,2045,2047],{"class":2046},"sBjJW",":",[1903,2049,2050],{"class":1913}," \"",[1903,2052,2053],{"class":2037},"$CURRENT_USER",[1903,2055,2056],{"class":1913},"\"\n",[1903,2058,2059],{"class":1905,"line":1926},[1903,2060,2061],{"class":2037},"}\n",[1844,2063,2064,2065,2068,2069,2000,2071,2012,2074,2076,2077,2080,2081,2083,2084,2086,2087],{},"Create another policy and name it  ",[1890,2066,2067],{},"Can Edit and Delete Own Posts",". Also, select the ",[1987,2070,1942],{},[1987,2072,2073],{},"Update",[1987,2075,2015],{}," in the options, and in the ",[1987,2078,2079],{},"Item Permissions",",  set ",[1890,2082,1946],{}," to ",[1890,2085,2053],{}," to only allow update actions for items created by the currently authenticated user. You also need to do the same thing for ",[1987,2088,2089],{},"Delete Permissions",[1844,2091,2092,2093,2096,2097,2100,2101,2103,2104,2106,2107,2109,2110,2112,2113,2116],{},"The last policy to create is a policy named ",[1890,2094,2095],{},"Can View and Edit Own Profile",". This time the permissions will be set for the ",[1890,2098,2099],{},"directus_users"," collection. Set the ",[1987,2102,2003],{}," to custom by clciking ",[1987,2105,2015],{},". In the ",[1987,2108,2079],{},", set id to ",[1890,2111,2053],{}," to only allow users to view their own profile. Also ensure to tick all the required fields in the ",[1987,2114,2115],{},"Field Permission"," section.",[1844,2118,2119,2120,2123],{},"Do the same thing for ",[2121,2122,2073],"em",{},"* permission (use the same Item Permissions as Read)",[1844,2125,2126],{},"For each policy you create, ensure that app access is enabled. App access auto-configures minimum permissions required to log in to the App.",[1933,2128,2130],{"id":2129},"enable-public-registration","Enable Public Registration",[1844,2132,2133],{},"Public registration allows any user to create a user in your Directus project directly from the Data Studio or via API.",[1844,2135,2136,2137,2140],{},"Navigate to ",[1987,2138,2139],{},"Project Settings -> User Registration"," and enable the setting. Set the default role to 'Authenticated User'.",[1844,2142,2143],{},[1971,2144],{"alt":2145,"src":2146},"Enable user registration","/img/user_registration_directus.png",[1844,2148,2149],{},"This role will automatically be assigned to new users, and it gives them all of the permissions you set up in the previous step.",[1840,2151,2153],{"id":2152},"set-up-your-sveltekit-project","Set Up Your SvelteKit Project",[1844,2155,2156],{},"To start building, you need to install SvelteKit and Directus sdk. Run this command:",[1895,2158,2160],{"className":1897,"code":2159,"language":1899,"meta":24,"style":24},"npx sv create directus-auth # choose SvelteKit minimal\n",[1890,2161,2162],{"__ignoreMap":24},[1903,2163,2164,2167,2170,2173,2176],{"class":1905,"line":1906},[1903,2165,2166],{"class":1909},"npx",[1903,2168,2169],{"class":1913}," sv",[1903,2171,2172],{"class":1913}," create",[1903,2174,2175],{"class":1913}," directus-auth",[1903,2177,2179],{"class":2178},"sCsY4"," # choose SvelteKit minimal\n",[1844,2181,2182],{},"When prompted, select SvelteKit minimal as the template. Do not add type checking, as this tutorial is implemented using JavaScript. Your output should look like this:",[1895,2184,2186],{"className":1897,"code":2185,"language":1899,"meta":24,"style":24}," Welcome to the Svelte CLI! (v0.6.16)\n│\n◇  Which template would you like?\n│  SvelteKit minimal\n│\n◇  Add type checking with Typescript?\n│  No\n│\n◆  Project created\n│\n◇  What would you like to add to your project? (use arrow keys / space bar)\n│  none\n│\n◇  Which package manager do you want to install dependencies with?\n│  npm\n│\n◆  Successfully installed dependencies\n│\n◇  Project next steps ─────────────────────────────────────────────────────╮\n│                                                                          │\n│  1: cd preview-app                                                       │\n│  2: git init && git add -A && git commit -m \"Initial commit\" (optional)  │\n│  3: npm run dev -- --open\n",[1890,2187,2188,2208,2213,2233,2245,2250,2270,2278,2283,2295,2300,2349,2357,2362,2394,2402,2407,2421,2426,2442,2450,2467,2508],{"__ignoreMap":24},[1903,2189,2190,2193,2196,2199,2202,2205],{"class":1905,"line":1906},[1903,2191,2192],{"class":1909}," Welcome",[1903,2194,2195],{"class":1913}," to",[1903,2197,2198],{"class":1913}," the",[1903,2200,2201],{"class":1913}," Svelte",[1903,2203,2204],{"class":1913}," CLI!",[1903,2206,2207],{"class":2037}," (v0.6.16)\n",[1903,2209,2210],{"class":1905,"line":1917},[1903,2211,2212],{"class":1909},"│\n",[1903,2214,2215,2218,2221,2224,2227,2230],{"class":1905,"line":1926},[1903,2216,2217],{"class":1909},"◇",[1903,2219,2220],{"class":1913},"  Which",[1903,2222,2223],{"class":1913}," template",[1903,2225,2226],{"class":1913}," would",[1903,2228,2229],{"class":1913}," you",[1903,2231,2232],{"class":1913}," like?\n",[1903,2234,2236,2239,2242],{"class":1905,"line":2235},4,[1903,2237,2238],{"class":1909},"│",[1903,2240,2241],{"class":1913},"  SvelteKit",[1903,2243,2244],{"class":1913}," minimal\n",[1903,2246,2248],{"class":1905,"line":2247},5,[1903,2249,2212],{"class":1909},[1903,2251,2253,2255,2258,2261,2264,2267],{"class":1905,"line":2252},6,[1903,2254,2217],{"class":1909},[1903,2256,2257],{"class":1913},"  Add",[1903,2259,2260],{"class":1913}," type",[1903,2262,2263],{"class":1913}," checking",[1903,2265,2266],{"class":1913}," with",[1903,2268,2269],{"class":1913}," Typescript?\n",[1903,2271,2273,2275],{"class":1905,"line":2272},7,[1903,2274,2238],{"class":1909},[1903,2276,2277],{"class":1913},"  No\n",[1903,2279,2281],{"class":1905,"line":2280},8,[1903,2282,2212],{"class":1909},[1903,2284,2286,2289,2292],{"class":1905,"line":2285},9,[1903,2287,2288],{"class":1909},"◆",[1903,2290,2291],{"class":1913},"  Project",[1903,2293,2294],{"class":1913}," created\n",[1903,2296,2298],{"class":1905,"line":2297},10,[1903,2299,2212],{"class":1909},[1903,2301,2303,2305,2308,2310,2312,2315,2317,2320,2322,2325,2328,2331,2334,2337,2340,2343,2346],{"class":1905,"line":2302},11,[1903,2304,2217],{"class":1909},[1903,2306,2307],{"class":1913},"  What",[1903,2309,2226],{"class":1913},[1903,2311,2229],{"class":1913},[1903,2313,2314],{"class":1913}," like",[1903,2316,2195],{"class":1913},[1903,2318,2319],{"class":1913}," add",[1903,2321,2195],{"class":1913},[1903,2323,2324],{"class":1913}," your",[1903,2326,2327],{"class":1913}," project?",[1903,2329,2330],{"class":2037}," (use ",[1903,2332,2333],{"class":1913},"arrow",[1903,2335,2336],{"class":1913}," keys",[1903,2338,2339],{"class":1913}," /",[1903,2341,2342],{"class":1913}," space",[1903,2344,2345],{"class":1913}," bar",[1903,2347,2348],{"class":2037},")\n",[1903,2350,2352,2354],{"class":1905,"line":2351},12,[1903,2353,2238],{"class":1909},[1903,2355,2356],{"class":1913},"  none\n",[1903,2358,2360],{"class":1905,"line":2359},13,[1903,2361,2212],{"class":1909},[1903,2363,2365,2367,2369,2372,2375,2378,2380,2383,2385,2388,2391],{"class":1905,"line":2364},14,[1903,2366,2217],{"class":1909},[1903,2368,2220],{"class":1913},[1903,2370,2371],{"class":1913}," package",[1903,2373,2374],{"class":1913}," manager",[1903,2376,2377],{"class":1913}," do",[1903,2379,2229],{"class":1913},[1903,2381,2382],{"class":1913}," want",[1903,2384,2195],{"class":1913},[1903,2386,2387],{"class":1913}," install",[1903,2389,2390],{"class":1913}," dependencies",[1903,2392,2393],{"class":1913}," with?\n",[1903,2395,2397,2399],{"class":1905,"line":2396},15,[1903,2398,2238],{"class":1909},[1903,2400,2401],{"class":1913},"  npm\n",[1903,2403,2405],{"class":1905,"line":2404},16,[1903,2406,2212],{"class":1909},[1903,2408,2410,2412,2415,2418],{"class":1905,"line":2409},17,[1903,2411,2288],{"class":1909},[1903,2413,2414],{"class":1913},"  Successfully",[1903,2416,2417],{"class":1913}," installed",[1903,2419,2420],{"class":1913}," dependencies\n",[1903,2422,2424],{"class":1905,"line":2423},18,[1903,2425,2212],{"class":1909},[1903,2427,2429,2431,2433,2436,2439],{"class":1905,"line":2428},19,[1903,2430,2217],{"class":1909},[1903,2432,2291],{"class":1913},[1903,2434,2435],{"class":1913}," next",[1903,2437,2438],{"class":1913}," steps",[1903,2440,2441],{"class":1913}," ─────────────────────────────────────────────────────╮\n",[1903,2443,2445,2447],{"class":1905,"line":2444},20,[1903,2446,2238],{"class":1909},[1903,2448,2449],{"class":1913},"                                                                          │\n",[1903,2451,2453,2455,2458,2461,2464],{"class":1905,"line":2452},21,[1903,2454,2238],{"class":1909},[1903,2456,2457],{"class":1913},"  1:",[1903,2459,2460],{"class":1913}," cd",[1903,2462,2463],{"class":1913}," preview-app",[1903,2465,2466],{"class":1913},"                                                       │\n",[1903,2468,2470,2472,2475,2478,2481,2484,2487,2489,2492,2494,2496,2499,2502,2505],{"class":1905,"line":2469},22,[1903,2471,2238],{"class":1909},[1903,2473,2474],{"class":1913},"  2:",[1903,2476,2477],{"class":1913}," git",[1903,2479,2480],{"class":1913}," init",[1903,2482,2483],{"class":2037}," && ",[1903,2485,2486],{"class":1909},"git",[1903,2488,2319],{"class":1913},[1903,2490,2491],{"class":2046}," -A",[1903,2493,2483],{"class":2037},[1903,2495,2486],{"class":1909},[1903,2497,2498],{"class":1913}," commit",[1903,2500,2501],{"class":2046}," -m",[1903,2503,2504],{"class":1913}," \"Initial commit\"",[1903,2506,2507],{"class":2037}," (optional)  │\n",[1903,2509,2511,2513,2516,2519,2522,2525,2528],{"class":1905,"line":2510},23,[1903,2512,2238],{"class":1909},[1903,2514,2515],{"class":1913},"  3:",[1903,2517,2518],{"class":1913}," npm",[1903,2520,2521],{"class":1913}," run",[1903,2523,2524],{"class":1913}," dev",[1903,2526,2527],{"class":2046}," --",[1903,2529,2530],{"class":2046}," --open\n",[1844,2532,2533,2534,2537],{},"Afterwards, ",[1890,2535,2536],{},"cd"," into your project directory and run:",[1895,2539,2541],{"className":1897,"code":2540,"language":1899,"meta":24,"style":24},"npm install\n",[1890,2542,2543],{"__ignoreMap":24},[1903,2544,2545,2548],{"class":1905,"line":1906},[1903,2546,2547],{"class":1909},"npm",[1903,2549,2550],{"class":1913}," install\n",[1844,2552,2553],{},"This will install all the dependencies for the project.",[1844,2555,2556],{},"Lastly, you need to install the Directus SDK. Run this command:",[1895,2558,2560],{"className":1897,"code":2559,"language":1899,"meta":24,"style":24},"npm install @directus/sdk\n",[1890,2561,2562],{"__ignoreMap":24},[1903,2563,2564,2566,2568],{"class":1905,"line":1906},[1903,2565,2547],{"class":1909},[1903,2567,2387],{"class":1913},[1903,2569,2570],{"class":1913}," @directus/sdk\n",[1933,2572,2574],{"id":2573},"configure-the-directus-sdk","Configure the Directus SDK",[1844,2576,2577,2578,2581,2582,2585],{},"You need to configure Directus SDK in your project. Create a file called ",[1890,2579,2580],{},"directus.js"," inside the ",[1890,2583,2584],{},"./src/lib"," directory. Add the following code:",[1895,2587,2591],{"className":2588,"code":2589,"language":2590,"meta":24,"style":24},"language-javascript shiki shiki-themes github-light github-light github-dark","// src/lib/directus.js\nimport { createDirectus, rest } from \"@directus/sdk\";\nconst directusUrl = \"http://localhost:8055\";\nexport const client = createDirectus(directusUrl).with(rest());\n","javascript",[1890,2592,2593,2598,2616,2632],{"__ignoreMap":24},[1903,2594,2595],{"class":1905,"line":1906},[1903,2596,2597],{"class":2178},"// src/lib/directus.js\n",[1903,2599,2600,2604,2607,2610,2613],{"class":1905,"line":1917},[1903,2601,2603],{"class":2602},"s8jYJ","import",[1903,2605,2606],{"class":2037}," { createDirectus, rest } ",[1903,2608,2609],{"class":2602},"from",[1903,2611,2612],{"class":1913}," \"@directus/sdk\"",[1903,2614,2615],{"class":2037},";\n",[1903,2617,2618,2621,2624,2627,2630],{"class":1905,"line":1926},[1903,2619,2620],{"class":2602},"const",[1903,2622,2623],{"class":2046}," directusUrl",[1903,2625,2626],{"class":2602}," =",[1903,2628,2629],{"class":1913}," \"http://localhost:8055\"",[1903,2631,2615],{"class":2037},[1903,2633,2634,2637,2640,2643,2645,2648,2651,2654,2657,2660],{"class":1905,"line":2235},[1903,2635,2636],{"class":2602},"export",[1903,2638,2639],{"class":2602}," const",[1903,2641,2642],{"class":2046}," client",[1903,2644,2626],{"class":2602},[1903,2646,2647],{"class":1909}," createDirectus",[1903,2649,2650],{"class":2037},"(directusUrl).",[1903,2652,2653],{"class":1909},"with",[1903,2655,2656],{"class":2037},"(",[1903,2658,2659],{"class":1909},"rest",[1903,2661,2662],{"class":2037},"());\n",[1844,2664,2665],{},"This setups Directus client with the authentication composable. And will be updated as we progress in the tutorial.",[1933,2667,2669],{"id":2668},"implement-user-registration","Implement User Registration",[1844,2671,2672,2673,2581,2676,2679,2680,2683],{},"In the following step, you will create a component to handle registering user and save their credentials on the Directus backend. Create a subdirectory called ",[1890,2674,2675],{},"register",[1890,2677,2678],{},"./src/routes"," directory, and inside it, create a file ",[1890,2681,2682],{},"+page.svelte"," file, with the following code:",[1895,2685,2687],{"className":2588,"code":2686,"language":2590,"meta":24,"style":24},"// src/routes/register/+page.svelte\n\n\u003Cscript>\n  import { client } from \"../../lib/directus\";\n  import { registerUser } from \"@directus/sdk\";\n  import { goto } from \"$app/navigation\";\n  let email = \"\";\n  let password = \"\";\n  let firstName = \"\";\n  let lastName = \"\";\n  let error = null;\n\n  async function handleRegister() {\n    try {\n      const response = await client.request(\n        registerUser(email, password, {\n          first_name: firstName,\n          last_name: lastName,\n        })\n      );\n      console.log(\"response>>>>>\", response);\n      goto(\"/login\");\n    } catch (err) {\n      error = err.message;\n      console.error(err);\n    }\n  }\n\u003C/script>\n\n\u003Cdiv class=\"container\">\n  \u003Ch1>Create Account\u003C/h1>\n\n  {#if error}\n    \u003Cp class=\"error\">{error}\u003C/p>\n  {/if}\n\n  \u003Cform on:submit|preventDefault={handleRegister}>\n    \u003Cdiv class=\"form-group\">\n      \u003Cinput\n        type=\"text\"\n        bind:value={firstName}\n        placeholder=\"First Name\"\n        required\n      />\n      \u003Cinput\n        type=\"text\"\n        bind:value={lastName}\n        placeholder=\"Last Name\"\n        required\n      />\n    \u003C/div>\n    \u003Cinput type=\"email\" bind:value={email} placeholder=\"Email\" required />\n    \u003Cinput\n      type=\"password\"\n      bind:value={password}\n      placeholder=\"Password\"\n      required\n    />\n    \u003Cbutton type=\"submit\">Register\u003C/button>\n  \u003C/form>\n  \u003Cp class=\"login-link\">\n    Already have an account? \u003Ca href=\"/login\">Login here\u003C/a>\n  \u003C/p>\n\u003C/div>\n",[1890,2688,2689,2694,2700,2712,2717,2722,2727,2732,2737,2742,2747,2752,2756,2761,2766,2786,2794,2799,2804,2809,2814,2825,2838,2849,2860,2866,2872,2878,2888,2893,2911,2927,2932,2938,2960,2972,2977,2989,3004,3013,3024,3040,3051,3057,3063,3070,3079,3093,3103,3108,3113,3123,3164,3171,3182,3197,3208,3214,3220,3242,3252,3268,3290,3299],{"__ignoreMap":24},[1903,2690,2691],{"class":1905,"line":1906},[1903,2692,2693],{"class":2178},"// src/routes/register/+page.svelte\n",[1903,2695,2696],{"class":1905,"line":1917},[1903,2697,2699],{"emptyLinePlaceholder":2698},true,"\n",[1903,2701,2702,2705,2709],{"class":1905,"line":1926},[1903,2703,2704],{"class":2037},"\u003C",[1903,2706,2708],{"class":2707},"sovSZ","script",[1903,2710,2711],{"class":2037},">\n",[1903,2713,2714],{"class":1905,"line":2235},[1903,2715,2716],{"class":2037},"  import { client } from \"../../lib/directus\";\n",[1903,2718,2719],{"class":1905,"line":2247},[1903,2720,2721],{"class":2037},"  import { registerUser } from \"@directus/sdk\";\n",[1903,2723,2724],{"class":1905,"line":2252},[1903,2725,2726],{"class":2037},"  import { goto } from \"$app/navigation\";\n",[1903,2728,2729],{"class":1905,"line":2272},[1903,2730,2731],{"class":2037},"  let email = \"\";\n",[1903,2733,2734],{"class":1905,"line":2280},[1903,2735,2736],{"class":2037},"  let password = \"\";\n",[1903,2738,2739],{"class":1905,"line":2285},[1903,2740,2741],{"class":2037},"  let firstName = \"\";\n",[1903,2743,2744],{"class":1905,"line":2297},[1903,2745,2746],{"class":2037},"  let lastName = \"\";\n",[1903,2748,2749],{"class":1905,"line":2302},[1903,2750,2751],{"class":2037},"  let error = null;\n",[1903,2753,2754],{"class":1905,"line":2351},[1903,2755,2699],{"emptyLinePlaceholder":2698},[1903,2757,2758],{"class":1905,"line":2359},[1903,2759,2760],{"class":2037},"  async function handleRegister() {\n",[1903,2762,2763],{"class":1905,"line":2364},[1903,2764,2765],{"class":2037},"    try {\n",[1903,2767,2768,2771,2774,2777,2780,2783],{"class":1905,"line":2396},[1903,2769,2770],{"class":2037},"      const response ",[1903,2772,2773],{"class":2602},"=",[1903,2775,2776],{"class":2602}," await",[1903,2778,2779],{"class":2037}," client.",[1903,2781,2782],{"class":1909},"request",[1903,2784,2785],{"class":2037},"(\n",[1903,2787,2788,2791],{"class":1905,"line":2404},[1903,2789,2790],{"class":1909},"        registerUser",[1903,2792,2793],{"class":2037},"(email, password, {\n",[1903,2795,2796],{"class":1905,"line":2409},[1903,2797,2798],{"class":2037},"          first_name: firstName,\n",[1903,2800,2801],{"class":1905,"line":2423},[1903,2802,2803],{"class":2037},"          last_name: lastName,\n",[1903,2805,2806],{"class":1905,"line":2428},[1903,2807,2808],{"class":2037},"        })\n",[1903,2810,2811],{"class":1905,"line":2444},[1903,2812,2813],{"class":2037},"      );\n",[1903,2815,2816,2819,2822],{"class":1905,"line":2452},[1903,2817,2818],{"class":2037},"      console.log(",[1903,2820,2821],{"class":1913},"\"response>>>>>\"",[1903,2823,2824],{"class":2037},", response);\n",[1903,2826,2827,2830,2832,2835],{"class":1905,"line":2469},[1903,2828,2829],{"class":1909},"      goto",[1903,2831,2656],{"class":2037},[1903,2833,2834],{"class":1913},"\"/login\"",[1903,2836,2837],{"class":2037},");\n",[1903,2839,2840,2843,2846],{"class":1905,"line":2510},[1903,2841,2842],{"class":2037},"    } ",[1903,2844,2845],{"class":1909},"catch",[1903,2847,2848],{"class":2037}," (err) {\n",[1903,2850,2852,2855,2857],{"class":1905,"line":2851},24,[1903,2853,2854],{"class":2037},"      error ",[1903,2856,2773],{"class":2602},[1903,2858,2859],{"class":2037}," err.message;\n",[1903,2861,2863],{"class":1905,"line":2862},25,[1903,2864,2865],{"class":2037},"      console.error(err);\n",[1903,2867,2869],{"class":1905,"line":2868},26,[1903,2870,2871],{"class":2037},"    }\n",[1903,2873,2875],{"class":1905,"line":2874},27,[1903,2876,2877],{"class":2037},"  }\n",[1903,2879,2881,2884,2886],{"class":1905,"line":2880},28,[1903,2882,2883],{"class":2037},"\u003C/",[1903,2885,2708],{"class":2707},[1903,2887,2711],{"class":2037},[1903,2889,2891],{"class":1905,"line":2890},29,[1903,2892,2699],{"emptyLinePlaceholder":2698},[1903,2894,2896,2898,2901,2904,2906,2909],{"class":1905,"line":2895},30,[1903,2897,2704],{"class":2037},[1903,2899,2900],{"class":2707},"div",[1903,2902,2903],{"class":1909}," class",[1903,2905,2773],{"class":2602},[1903,2907,2908],{"class":1913},"\"container\"",[1903,2910,2711],{"class":2037},[1903,2912,2914,2917,2920,2923,2925],{"class":1905,"line":2913},31,[1903,2915,2916],{"class":2037},"  \u003C",[1903,2918,2919],{"class":2707},"h1",[1903,2921,2922],{"class":2037},">Create Account\u003C/",[1903,2924,2919],{"class":2707},[1903,2926,2711],{"class":2037},[1903,2928,2930],{"class":1905,"line":2929},32,[1903,2931,2699],{"emptyLinePlaceholder":2698},[1903,2933,2935],{"class":1905,"line":2934},33,[1903,2936,2937],{"class":2037},"  {#if error}\n",[1903,2939,2941,2944,2946,2948,2950,2953,2956,2958],{"class":1905,"line":2940},34,[1903,2942,2943],{"class":2037},"    \u003C",[1903,2945,1844],{"class":2707},[1903,2947,2903],{"class":1909},[1903,2949,2773],{"class":2602},[1903,2951,2952],{"class":1913},"\"error\"",[1903,2954,2955],{"class":2037},">{error}\u003C/",[1903,2957,1844],{"class":2707},[1903,2959,2711],{"class":2037},[1903,2961,2963,2966,2969],{"class":1905,"line":2962},35,[1903,2964,2965],{"class":2037},"  {",[1903,2967,2968],{"class":2602},"/",[1903,2970,2971],{"class":2037},"if}\n",[1903,2973,2975],{"class":1905,"line":2974},36,[1903,2976,2699],{"emptyLinePlaceholder":2698},[1903,2978,2980,2982,2985],{"class":1905,"line":2979},37,[1903,2981,2916],{"class":2037},[1903,2983,2984],{"class":2707},"form",[1903,2986,2988],{"class":2987},"sPrNH"," on:submit|preventDefault={handleRegister}>\n",[1903,2990,2992,2995,2997,2999,3002],{"class":1905,"line":2991},38,[1903,2993,2994],{"class":2987},"    \u003Cdiv",[1903,2996,2903],{"class":1909},[1903,2998,2773],{"class":2602},[1903,3000,3001],{"class":1913},"\"form-group\"",[1903,3003,2711],{"class":2037},[1903,3005,3007,3010],{"class":1905,"line":3006},39,[1903,3008,3009],{"class":2037},"      \u003C",[1903,3011,3012],{"class":2707},"input\n",[1903,3014,3016,3019,3021],{"class":1905,"line":3015},40,[1903,3017,3018],{"class":1909},"        type",[1903,3020,2773],{"class":2602},[1903,3022,3023],{"class":1913},"\"text\"\n",[1903,3025,3027,3030,3032,3035,3037],{"class":1905,"line":3026},41,[1903,3028,3029],{"class":1909},"        bind",[1903,3031,2047],{"class":2037},[1903,3033,3034],{"class":1909},"value",[1903,3036,2773],{"class":2602},[1903,3038,3039],{"class":2037},"{firstName}\n",[1903,3041,3043,3046,3048],{"class":1905,"line":3042},42,[1903,3044,3045],{"class":1909},"        placeholder",[1903,3047,2773],{"class":2602},[1903,3049,3050],{"class":1913},"\"First Name\"\n",[1903,3052,3054],{"class":1905,"line":3053},43,[1903,3055,3056],{"class":1909},"        required\n",[1903,3058,3060],{"class":1905,"line":3059},44,[1903,3061,3062],{"class":2037},"      />\n",[1903,3064,3066,3068],{"class":1905,"line":3065},45,[1903,3067,3009],{"class":2037},[1903,3069,3012],{"class":2707},[1903,3071,3073,3075,3077],{"class":1905,"line":3072},46,[1903,3074,3018],{"class":1909},[1903,3076,2773],{"class":2602},[1903,3078,3023],{"class":1913},[1903,3080,3082,3084,3086,3088,3090],{"class":1905,"line":3081},47,[1903,3083,3029],{"class":1909},[1903,3085,2047],{"class":2037},[1903,3087,3034],{"class":1909},[1903,3089,2773],{"class":2602},[1903,3091,3092],{"class":2037},"{lastName}\n",[1903,3094,3096,3098,3100],{"class":1905,"line":3095},48,[1903,3097,3045],{"class":1909},[1903,3099,2773],{"class":2602},[1903,3101,3102],{"class":1913},"\"Last Name\"\n",[1903,3104,3106],{"class":1905,"line":3105},49,[1903,3107,3056],{"class":1909},[1903,3109,3111],{"class":1905,"line":3110},50,[1903,3112,3062],{"class":2037},[1903,3114,3116,3119,3121],{"class":1905,"line":3115},51,[1903,3117,3118],{"class":2037},"    \u003C/",[1903,3120,2900],{"class":2707},[1903,3122,2711],{"class":2037},[1903,3124,3126,3128,3131,3133,3135,3138,3141,3143,3145,3147,3150,3153,3155,3158,3161],{"class":1905,"line":3125},52,[1903,3127,2943],{"class":2037},[1903,3129,3130],{"class":2707},"input",[1903,3132,2260],{"class":1909},[1903,3134,2773],{"class":2602},[1903,3136,3137],{"class":1913},"\"email\"",[1903,3139,3140],{"class":1909}," bind",[1903,3142,2047],{"class":2037},[1903,3144,3034],{"class":1909},[1903,3146,2773],{"class":2602},[1903,3148,3149],{"class":2037},"{email} ",[1903,3151,3152],{"class":1909},"placeholder",[1903,3154,2773],{"class":2602},[1903,3156,3157],{"class":1913},"\"Email\"",[1903,3159,3160],{"class":1909}," required",[1903,3162,3163],{"class":2037}," />\n",[1903,3165,3167,3169],{"class":1905,"line":3166},53,[1903,3168,2943],{"class":2037},[1903,3170,3012],{"class":2707},[1903,3172,3174,3177,3179],{"class":1905,"line":3173},54,[1903,3175,3176],{"class":1909},"      type",[1903,3178,2773],{"class":2602},[1903,3180,3181],{"class":1913},"\"password\"\n",[1903,3183,3185,3188,3190,3192,3194],{"class":1905,"line":3184},55,[1903,3186,3187],{"class":1909},"      bind",[1903,3189,2047],{"class":2037},[1903,3191,3034],{"class":1909},[1903,3193,2773],{"class":2602},[1903,3195,3196],{"class":2037},"{password}\n",[1903,3198,3200,3203,3205],{"class":1905,"line":3199},56,[1903,3201,3202],{"class":1909},"      placeholder",[1903,3204,2773],{"class":2602},[1903,3206,3207],{"class":1913},"\"Password\"\n",[1903,3209,3211],{"class":1905,"line":3210},57,[1903,3212,3213],{"class":1909},"      required\n",[1903,3215,3217],{"class":1905,"line":3216},58,[1903,3218,3219],{"class":2037},"    />\n",[1903,3221,3223,3225,3228,3230,3232,3235,3238,3240],{"class":1905,"line":3222},59,[1903,3224,2943],{"class":2037},[1903,3226,3227],{"class":2707},"button",[1903,3229,2260],{"class":1909},[1903,3231,2773],{"class":2602},[1903,3233,3234],{"class":1913},"\"submit\"",[1903,3236,3237],{"class":2037},">Register\u003C/",[1903,3239,3227],{"class":2707},[1903,3241,2711],{"class":2037},[1903,3243,3245,3248,3250],{"class":1905,"line":3244},60,[1903,3246,3247],{"class":2037},"  \u003C/",[1903,3249,2984],{"class":2707},[1903,3251,2711],{"class":2037},[1903,3253,3255,3257,3259,3261,3263,3266],{"class":1905,"line":3254},61,[1903,3256,2916],{"class":2037},[1903,3258,1844],{"class":2707},[1903,3260,2903],{"class":1909},[1903,3262,2773],{"class":2602},[1903,3264,3265],{"class":1913},"\"login-link\"",[1903,3267,2711],{"class":2037},[1903,3269,3271,3274,3276,3279,3281,3283,3286,3288],{"class":1905,"line":3270},62,[1903,3272,3273],{"class":2037},"    Already have an account? \u003C",[1903,3275,1862],{"class":2707},[1903,3277,3278],{"class":1909}," href",[1903,3280,2773],{"class":2602},[1903,3282,2834],{"class":1913},[1903,3284,3285],{"class":2037},">Login here\u003C/",[1903,3287,1862],{"class":2707},[1903,3289,2711],{"class":2037},[1903,3291,3293,3295,3297],{"class":1905,"line":3292},63,[1903,3294,3247],{"class":2037},[1903,3296,1844],{"class":2707},[1903,3298,2711],{"class":2037},[1903,3300,3302,3304,3306],{"class":1905,"line":3301},64,[1903,3303,2883],{"class":2602},[1903,3305,2900],{"class":2037},[1903,3307,2711],{"class":2602},[1844,3309,3310,3311,3314],{},"The above code snippet is a form that collects the user's credentials, which are the name, email, and password, submits it, and sends a request to the Directus server via the ",[1890,3312,3313],{},"handleRegister"," function. If the registration is successful, the user is then redirected to the login page, which will be created below.",[1933,3316,3318],{"id":3317},"implement-user-login","Implement User Login",[1844,3320,3321,3322,2581,3325,2679,3327,3329],{},"In the following step, you will create a login component where the users will be directed to log in. Create a subdirectory called ",[1890,3323,3324],{},"login",[1890,3326,2678],{},[1890,3328,2682],{}," file with the following code:",[1895,3331,3333],{"className":2588,"code":3332,"language":2590,"meta":24,"style":24},"\u003C!-- src/routes/login/+page.svelte -->\n\u003Cscript>\n  import { client, isAuthenticated } from \"../../lib/directus.js\";\n  import { goto } from \"$app/navigation\";\n\n  let email = \"\";\n  let password = \"\";\n  let error = null;\n\n  async function handleLogin() {\n    try {\n      // Call the login method directly from the client\n      const result = await client.login({ email, password });\n      console.log(\"Login successful:\", result);\n\n      // Check if the user is authenticated\n      const authStatus = await isAuthenticated();\n      console.log(\"Authentication status:\", authStatus);\n\n      if (authStatus.authenticated) {\n        goto(\"/protected\");\n      } else {\n        error = \"Failed to authenticate. Please try again.\";\n      }\n    } catch (err) {\n      if (err.response?.status === 403) {\n        error = \"Invalid email or password.\";\n      } else {\n        error = err.message || \"Login failed.\";\n      }\n      console.error(\"Login error:\", err);\n    }\n  }\n\u003C/script>\n\n\u003Cdiv>\n  \u003Ch1 style=\"color: #000;\">Welcome Back\u003C/h1>\n\n  {#if error}\n    \u003Cdiv>\n      \u003Cp>{error}\u003C/p>\n    \u003C/div>\n  {/if}\n\n  \u003Cform on:submit|preventDefault={handleLogin}>\n    \u003Cdiv>\n      \u003Cinput\n        type=\"email\"\n        bind:value={email}\n        placeholder=\"Email\"\n        required\n        autocomplete=\"email\"\n      />\n    \u003C/div>\n    \u003Cdiv>\n      \u003Cinput\n        type=\"password\"\n        bind:value={password}\n        placeholder=\"Password\"\n        required\n      />\n    \u003C/div>\n    \u003Cbutton type=\"submit\">Sign In\u003C/button>\n  \u003C/form>\n\n  \u003Cp style=\"color: #000;\">\n    Don't have an account? \u003Ca href=\"/register\">Register here\u003C/a>\n  \u003C/p>\n\u003C/div>\n",[1890,3334,3335,3361,3369,3374,3378,3382,3386,3390,3394,3398,3403,3407,3412,3428,3438,3442,3447,3462,3472,3476,3484,3496,3501,3513,3518,3526,3533,3544,3548,3565,3569,3580,3584,3588,3596,3600,3608,3629,3633,3637,3645,3657,3665,3673,3677,3686,3691,3696,3705,3718,3727,3731,3740,3744,3752,3760,3766,3774,3786,3794,3798,3802,3810,3829,3837,3842,3857,3879,3888],{"__ignoreMap":24},[1903,3336,3337,3340,3343,3345,3348,3350,3352,3355,3358],{"class":1905,"line":1906},[1903,3338,3339],{"class":2602},"\u003C!--",[1903,3341,3342],{"class":2037}," src",[1903,3344,2968],{"class":2602},[1903,3346,3347],{"class":2037},"routes",[1903,3349,2968],{"class":2602},[1903,3351,3324],{"class":2037},[1903,3353,3354],{"class":2602},"/+",[1903,3356,3357],{"class":2037},"page.svelte ",[1903,3359,3360],{"class":2602},"-->\n",[1903,3362,3363,3365,3367],{"class":1905,"line":1917},[1903,3364,2704],{"class":2037},[1903,3366,2708],{"class":2707},[1903,3368,2711],{"class":2037},[1903,3370,3371],{"class":1905,"line":1926},[1903,3372,3373],{"class":2037},"  import { client, isAuthenticated } from \"../../lib/directus.js\";\n",[1903,3375,3376],{"class":1905,"line":2235},[1903,3377,2726],{"class":2037},[1903,3379,3380],{"class":1905,"line":2247},[1903,3381,2699],{"emptyLinePlaceholder":2698},[1903,3383,3384],{"class":1905,"line":2252},[1903,3385,2731],{"class":2037},[1903,3387,3388],{"class":1905,"line":2272},[1903,3389,2736],{"class":2037},[1903,3391,3392],{"class":1905,"line":2280},[1903,3393,2751],{"class":2037},[1903,3395,3396],{"class":1905,"line":2285},[1903,3397,2699],{"emptyLinePlaceholder":2698},[1903,3399,3400],{"class":1905,"line":2297},[1903,3401,3402],{"class":2037},"  async function handleLogin() {\n",[1903,3404,3405],{"class":1905,"line":2302},[1903,3406,2765],{"class":2037},[1903,3408,3409],{"class":1905,"line":2351},[1903,3410,3411],{"class":2178},"      // Call the login method directly from the client\n",[1903,3413,3414,3417,3419,3421,3423,3425],{"class":1905,"line":2359},[1903,3415,3416],{"class":2037},"      const result ",[1903,3418,2773],{"class":2602},[1903,3420,2776],{"class":2602},[1903,3422,2779],{"class":2037},[1903,3424,3324],{"class":1909},[1903,3426,3427],{"class":2037},"({ email, password });\n",[1903,3429,3430,3432,3435],{"class":1905,"line":2364},[1903,3431,2818],{"class":2037},[1903,3433,3434],{"class":1913},"\"Login successful:\"",[1903,3436,3437],{"class":2037},", result);\n",[1903,3439,3440],{"class":1905,"line":2396},[1903,3441,2699],{"emptyLinePlaceholder":2698},[1903,3443,3444],{"class":1905,"line":2404},[1903,3445,3446],{"class":2178},"      // Check if the user is authenticated\n",[1903,3448,3449,3452,3454,3456,3459],{"class":1905,"line":2409},[1903,3450,3451],{"class":2037},"      const authStatus ",[1903,3453,2773],{"class":2602},[1903,3455,2776],{"class":2602},[1903,3457,3458],{"class":1909}," isAuthenticated",[1903,3460,3461],{"class":2037},"();\n",[1903,3463,3464,3466,3469],{"class":1905,"line":2423},[1903,3465,2818],{"class":2037},[1903,3467,3468],{"class":1913},"\"Authentication status:\"",[1903,3470,3471],{"class":2037},", authStatus);\n",[1903,3473,3474],{"class":1905,"line":2428},[1903,3475,2699],{"emptyLinePlaceholder":2698},[1903,3477,3478,3481],{"class":1905,"line":2444},[1903,3479,3480],{"class":1909},"      if",[1903,3482,3483],{"class":2037}," (authStatus.authenticated) {\n",[1903,3485,3486,3489,3491,3494],{"class":1905,"line":2452},[1903,3487,3488],{"class":2602},"        goto",[1903,3490,2656],{"class":2037},[1903,3492,3493],{"class":1913},"\"/protected\"",[1903,3495,2837],{"class":2037},[1903,3497,3498],{"class":1905,"line":2469},[1903,3499,3500],{"class":2037},"      } else {\n",[1903,3502,3503,3506,3508,3511],{"class":1905,"line":2510},[1903,3504,3505],{"class":2037},"        error ",[1903,3507,2773],{"class":2602},[1903,3509,3510],{"class":1913}," \"Failed to authenticate. Please try again.\"",[1903,3512,2615],{"class":2037},[1903,3514,3515],{"class":1905,"line":2851},[1903,3516,3517],{"class":2037},"      }\n",[1903,3519,3520,3522,3524],{"class":1905,"line":2862},[1903,3521,2842],{"class":2037},[1903,3523,2845],{"class":1909},[1903,3525,2848],{"class":2037},[1903,3527,3528,3530],{"class":1905,"line":2868},[1903,3529,3480],{"class":1909},[1903,3531,3532],{"class":2037}," (err.response?.status === 403) {\n",[1903,3534,3535,3537,3539,3542],{"class":1905,"line":2874},[1903,3536,3505],{"class":2037},[1903,3538,2773],{"class":2602},[1903,3540,3541],{"class":1913}," \"Invalid email or password.\"",[1903,3543,2615],{"class":2037},[1903,3545,3546],{"class":1905,"line":2880},[1903,3547,3500],{"class":2037},[1903,3549,3550,3552,3554,3557,3560,3563],{"class":1905,"line":2890},[1903,3551,3505],{"class":2037},[1903,3553,2773],{"class":2602},[1903,3555,3556],{"class":2037}," err.message ",[1903,3558,3559],{"class":2602},"||",[1903,3561,3562],{"class":1913}," \"Login failed.\"",[1903,3564,2615],{"class":2037},[1903,3566,3567],{"class":1905,"line":2895},[1903,3568,3517],{"class":2037},[1903,3570,3571,3574,3577],{"class":1905,"line":2913},[1903,3572,3573],{"class":2037},"      console.error(",[1903,3575,3576],{"class":1913},"\"Login error:\"",[1903,3578,3579],{"class":2037},", err);\n",[1903,3581,3582],{"class":1905,"line":2929},[1903,3583,2871],{"class":2037},[1903,3585,3586],{"class":1905,"line":2934},[1903,3587,2877],{"class":2037},[1903,3589,3590,3592,3594],{"class":1905,"line":2940},[1903,3591,2883],{"class":2037},[1903,3593,2708],{"class":2707},[1903,3595,2711],{"class":2037},[1903,3597,3598],{"class":1905,"line":2962},[1903,3599,2699],{"emptyLinePlaceholder":2698},[1903,3601,3602,3604,3606],{"class":1905,"line":2974},[1903,3603,2704],{"class":2037},[1903,3605,2900],{"class":2707},[1903,3607,2711],{"class":2037},[1903,3609,3610,3612,3614,3617,3619,3622,3625,3627],{"class":1905,"line":2979},[1903,3611,2916],{"class":2037},[1903,3613,2919],{"class":2707},[1903,3615,3616],{"class":1909}," style",[1903,3618,2773],{"class":2602},[1903,3620,3621],{"class":1913},"\"color: #000;\"",[1903,3623,3624],{"class":2037},">Welcome Back\u003C/",[1903,3626,2919],{"class":2707},[1903,3628,2711],{"class":2037},[1903,3630,3631],{"class":1905,"line":2991},[1903,3632,2699],{"emptyLinePlaceholder":2698},[1903,3634,3635],{"class":1905,"line":3006},[1903,3636,2937],{"class":2037},[1903,3638,3639,3641,3643],{"class":1905,"line":3015},[1903,3640,2943],{"class":2037},[1903,3642,2900],{"class":2707},[1903,3644,2711],{"class":2037},[1903,3646,3647,3649,3651,3653,3655],{"class":1905,"line":3026},[1903,3648,3009],{"class":2037},[1903,3650,1844],{"class":2707},[1903,3652,2955],{"class":2037},[1903,3654,1844],{"class":2707},[1903,3656,2711],{"class":2037},[1903,3658,3659,3661,3663],{"class":1905,"line":3042},[1903,3660,3118],{"class":2037},[1903,3662,2900],{"class":2707},[1903,3664,2711],{"class":2037},[1903,3666,3667,3669,3671],{"class":1905,"line":3053},[1903,3668,2965],{"class":2037},[1903,3670,2968],{"class":2602},[1903,3672,2971],{"class":2037},[1903,3674,3675],{"class":1905,"line":3059},[1903,3676,2699],{"emptyLinePlaceholder":2698},[1903,3678,3679,3681,3683],{"class":1905,"line":3065},[1903,3680,2916],{"class":2037},[1903,3682,2984],{"class":2707},[1903,3684,3685],{"class":2987}," on:submit|preventDefault={handleLogin}>\n",[1903,3687,3688],{"class":1905,"line":3072},[1903,3689,3690],{"class":2987},"    \u003Cdiv>\n",[1903,3692,3693],{"class":1905,"line":3081},[1903,3694,3695],{"class":2987},"      \u003Cinput\n",[1903,3697,3698,3700,3702],{"class":1905,"line":3095},[1903,3699,3018],{"class":1909},[1903,3701,2773],{"class":2602},[1903,3703,3704],{"class":1913},"\"email\"\n",[1903,3706,3707,3709,3711,3713,3715],{"class":1905,"line":3105},[1903,3708,3029],{"class":1909},[1903,3710,2047],{"class":2037},[1903,3712,3034],{"class":1909},[1903,3714,2773],{"class":2602},[1903,3716,3717],{"class":2037},"{email}\n",[1903,3719,3720,3722,3724],{"class":1905,"line":3110},[1903,3721,3045],{"class":1909},[1903,3723,2773],{"class":2602},[1903,3725,3726],{"class":1913},"\"Email\"\n",[1903,3728,3729],{"class":1905,"line":3115},[1903,3730,3056],{"class":1909},[1903,3732,3733,3736,3738],{"class":1905,"line":3125},[1903,3734,3735],{"class":1909},"        autocomplete",[1903,3737,2773],{"class":2602},[1903,3739,3704],{"class":1913},[1903,3741,3742],{"class":1905,"line":3166},[1903,3743,3062],{"class":2037},[1903,3745,3746,3748,3750],{"class":1905,"line":3173},[1903,3747,3118],{"class":2037},[1903,3749,2900],{"class":2707},[1903,3751,2711],{"class":2037},[1903,3753,3754,3756,3758],{"class":1905,"line":3184},[1903,3755,2943],{"class":2037},[1903,3757,2900],{"class":2707},[1903,3759,2711],{"class":2037},[1903,3761,3762,3764],{"class":1905,"line":3199},[1903,3763,3009],{"class":2037},[1903,3765,3012],{"class":2707},[1903,3767,3768,3770,3772],{"class":1905,"line":3210},[1903,3769,3018],{"class":1909},[1903,3771,2773],{"class":2602},[1903,3773,3181],{"class":1913},[1903,3775,3776,3778,3780,3782,3784],{"class":1905,"line":3216},[1903,3777,3029],{"class":1909},[1903,3779,2047],{"class":2037},[1903,3781,3034],{"class":1909},[1903,3783,2773],{"class":2602},[1903,3785,3196],{"class":2037},[1903,3787,3788,3790,3792],{"class":1905,"line":3222},[1903,3789,3045],{"class":1909},[1903,3791,2773],{"class":2602},[1903,3793,3207],{"class":1913},[1903,3795,3796],{"class":1905,"line":3244},[1903,3797,3056],{"class":1909},[1903,3799,3800],{"class":1905,"line":3254},[1903,3801,3062],{"class":2037},[1903,3803,3804,3806,3808],{"class":1905,"line":3270},[1903,3805,3118],{"class":2037},[1903,3807,2900],{"class":2707},[1903,3809,2711],{"class":2037},[1903,3811,3812,3814,3816,3818,3820,3822,3825,3827],{"class":1905,"line":3292},[1903,3813,2943],{"class":2037},[1903,3815,3227],{"class":2707},[1903,3817,2260],{"class":1909},[1903,3819,2773],{"class":2602},[1903,3821,3234],{"class":1913},[1903,3823,3824],{"class":2037},">Sign In\u003C/",[1903,3826,3227],{"class":2707},[1903,3828,2711],{"class":2037},[1903,3830,3831,3833,3835],{"class":1905,"line":3301},[1903,3832,3247],{"class":2602},[1903,3834,2984],{"class":2037},[1903,3836,2711],{"class":2602},[1903,3838,3840],{"class":1905,"line":3839},65,[1903,3841,2699],{"emptyLinePlaceholder":2698},[1903,3843,3845,3847,3849,3851,3853,3855],{"class":1905,"line":3844},66,[1903,3846,2916],{"class":2037},[1903,3848,1844],{"class":2707},[1903,3850,3616],{"class":1909},[1903,3852,2773],{"class":2602},[1903,3854,3621],{"class":1913},[1903,3856,2711],{"class":2037},[1903,3858,3860,3863,3865,3867,3869,3872,3875,3877],{"class":1905,"line":3859},67,[1903,3861,3862],{"class":2037},"    Don't have an account? \u003C",[1903,3864,1862],{"class":2707},[1903,3866,3278],{"class":1909},[1903,3868,2773],{"class":2602},[1903,3870,3871],{"class":1913},"\"/register\"",[1903,3873,3874],{"class":2037},">Register here\u003C/",[1903,3876,1862],{"class":2707},[1903,3878,2711],{"class":2037},[1903,3880,3882,3884,3886],{"class":1905,"line":3881},68,[1903,3883,3247],{"class":2037},[1903,3885,1844],{"class":2707},[1903,3887,2711],{"class":2037},[1903,3889,3891,3893,3895],{"class":1905,"line":3890},69,[1903,3892,2883],{"class":2602},[1903,3894,2900],{"class":2037},[1903,3896,2711],{"class":2602},[1933,3898,3900],{"id":3899},"json-authentcation-mode","Json Authentcation mode",[1844,3902,3903,3904,3907],{},"Json Authentication mode is one of the two approaches Directus offers to authentication. It involves the server returning an access token and a refresh token in the response body during authentication. To use the json mode, update your authentication composable in your ",[1890,3905,3906],{},"./src/lib/directus.js"," file to this:",[1895,3909,3911],{"className":2588,"code":3910,"language":2590,"meta":24,"style":24},"// src/lib/directus.js\n\nimport {createDirectus, rest,authentication} from \"@directus/sdk\";\nconst directusUrl = \"http://localhost:8055\";\nexport const client = createDirectus(directusUrl)\n .with(authentication(\"json\"))\n .with(rest());\n",[1890,3912,3913,3917,3921,3934,3946,3961,3981],{"__ignoreMap":24},[1903,3914,3915],{"class":1905,"line":1906},[1903,3916,2597],{"class":2178},[1903,3918,3919],{"class":1905,"line":1917},[1903,3920,2699],{"emptyLinePlaceholder":2698},[1903,3922,3923,3925,3928,3930,3932],{"class":1905,"line":1926},[1903,3924,2603],{"class":2602},[1903,3926,3927],{"class":2037}," {createDirectus, rest,authentication} ",[1903,3929,2609],{"class":2602},[1903,3931,2612],{"class":1913},[1903,3933,2615],{"class":2037},[1903,3935,3936,3938,3940,3942,3944],{"class":1905,"line":2235},[1903,3937,2620],{"class":2602},[1903,3939,2623],{"class":2046},[1903,3941,2626],{"class":2602},[1903,3943,2629],{"class":1913},[1903,3945,2615],{"class":2037},[1903,3947,3948,3950,3952,3954,3956,3958],{"class":1905,"line":2247},[1903,3949,2636],{"class":2602},[1903,3951,2639],{"class":2602},[1903,3953,2642],{"class":2046},[1903,3955,2626],{"class":2602},[1903,3957,2647],{"class":1909},[1903,3959,3960],{"class":2037},"(directusUrl)\n",[1903,3962,3963,3966,3968,3970,3973,3975,3978],{"class":1905,"line":2252},[1903,3964,3965],{"class":2037}," .",[1903,3967,2653],{"class":1909},[1903,3969,2656],{"class":2037},[1903,3971,3972],{"class":1909},"authentication",[1903,3974,2656],{"class":2037},[1903,3976,3977],{"class":1913},"\"json\"",[1903,3979,3980],{"class":2037},"))\n",[1903,3982,3983,3985,3987,3989,3991],{"class":1905,"line":2272},[1903,3984,3965],{"class":2037},[1903,3986,2653],{"class":1909},[1903,3988,2656],{"class":2037},[1903,3990,2659],{"class":1909},[1903,3992,2662],{"class":2037},[1933,3994,3996],{"id":3995},"session-cookie-authentication-mode","Session Cookie Authentication Mode",[1844,3998,3999,4000,3907],{},"The session cookies authentication mode is a simpler way provided by Directus if you do not want to manage authentication in your local storage. Directus client retrieves the tokens and stores them as cookies in your browser session. To use the cookie mode, update your authentication composable in your ",[1890,4001,3906],{},[1895,4003,4005],{"className":2588,"code":4004,"language":2590,"meta":24,"style":24},"// src/lib/directus.js\nimport {createDirectus, rest,authentication} from \"@directus/sdk\";\nconst directusUrl = \"http://localhost:8055\";\nexport const client = createDirectus(directusUrl)\n .with(authentication(\"cookie\"))\n .with(rest());\n",[1890,4006,4007,4011,4023,4035,4049,4066],{"__ignoreMap":24},[1903,4008,4009],{"class":1905,"line":1906},[1903,4010,2597],{"class":2178},[1903,4012,4013,4015,4017,4019,4021],{"class":1905,"line":1917},[1903,4014,2603],{"class":2602},[1903,4016,3927],{"class":2037},[1903,4018,2609],{"class":2602},[1903,4020,2612],{"class":1913},[1903,4022,2615],{"class":2037},[1903,4024,4025,4027,4029,4031,4033],{"class":1905,"line":1926},[1903,4026,2620],{"class":2602},[1903,4028,2623],{"class":2046},[1903,4030,2626],{"class":2602},[1903,4032,2629],{"class":1913},[1903,4034,2615],{"class":2037},[1903,4036,4037,4039,4041,4043,4045,4047],{"class":1905,"line":2235},[1903,4038,2636],{"class":2602},[1903,4040,2639],{"class":2602},[1903,4042,2642],{"class":2046},[1903,4044,2626],{"class":2602},[1903,4046,2647],{"class":1909},[1903,4048,3960],{"class":2037},[1903,4050,4051,4053,4055,4057,4059,4061,4064],{"class":1905,"line":2247},[1903,4052,3965],{"class":2037},[1903,4054,2653],{"class":1909},[1903,4056,2656],{"class":2037},[1903,4058,3972],{"class":1909},[1903,4060,2656],{"class":2037},[1903,4062,4063],{"class":1913},"\"cookie\"",[1903,4065,3980],{"class":2037},[1903,4067,4068,4070,4072,4074,4076],{"class":1905,"line":2252},[1903,4069,3965],{"class":2037},[1903,4071,2653],{"class":1909},[1903,4073,2656],{"class":2037},[1903,4075,2659],{"class":1909},[1903,4077,2662],{"class":2037},[1933,4079,4081],{"id":4080},"check-if-the-user-is-authenticated","Check if the User is Authenticated",[1844,4083,4084],{},"The next thing you want to do is to perform an authentication check to see if the user is authenticated by attempting to fetch their information using the Directus client.",[1844,4086,4087,4088,4091],{},"Add the following function to the ",[1890,4089,4090],{},"src/lib/directus.js"," file:",[1895,4093,4095],{"className":2588,"code":4094,"language":2590,"meta":24,"style":24},"// src/lib/directus.js\n\nimport { readMe } from \"@directus/sdk\";\n\n\nexport const isAuthenticated = async () => {\n  try {\n    const user = await client.request(readMe());\n    return { authenticated: !!user?.id, user };\n  } catch (error) {\n    console.error(\"Error checking authentication:\", error);\n    return { authenticated: false, user: null };\n  }\n};\n",[1890,4096,4097,4101,4105,4118,4122,4126,4148,4155,4178,4192,4202,4218,4236,4240],{"__ignoreMap":24},[1903,4098,4099],{"class":1905,"line":1906},[1903,4100,2597],{"class":2178},[1903,4102,4103],{"class":1905,"line":1917},[1903,4104,2699],{"emptyLinePlaceholder":2698},[1903,4106,4107,4109,4112,4114,4116],{"class":1905,"line":1926},[1903,4108,2603],{"class":2602},[1903,4110,4111],{"class":2037}," { readMe } ",[1903,4113,2609],{"class":2602},[1903,4115,2612],{"class":1913},[1903,4117,2615],{"class":2037},[1903,4119,4120],{"class":1905,"line":2235},[1903,4121,2699],{"emptyLinePlaceholder":2698},[1903,4123,4124],{"class":1905,"line":2247},[1903,4125,2699],{"emptyLinePlaceholder":2698},[1903,4127,4128,4130,4132,4134,4136,4139,4142,4145],{"class":1905,"line":2252},[1903,4129,2636],{"class":2602},[1903,4131,2639],{"class":2602},[1903,4133,3458],{"class":1909},[1903,4135,2626],{"class":2602},[1903,4137,4138],{"class":2602}," async",[1903,4140,4141],{"class":2037}," () ",[1903,4143,4144],{"class":2602},"=>",[1903,4146,4147],{"class":2037}," {\n",[1903,4149,4150,4153],{"class":1905,"line":2272},[1903,4151,4152],{"class":2602},"  try",[1903,4154,4147],{"class":2037},[1903,4156,4157,4160,4163,4165,4167,4169,4171,4173,4176],{"class":1905,"line":2280},[1903,4158,4159],{"class":2602},"    const",[1903,4161,4162],{"class":2046}," user",[1903,4164,2626],{"class":2602},[1903,4166,2776],{"class":2602},[1903,4168,2779],{"class":2037},[1903,4170,2782],{"class":1909},[1903,4172,2656],{"class":2037},[1903,4174,4175],{"class":1909},"readMe",[1903,4177,2662],{"class":2037},[1903,4179,4180,4183,4186,4189],{"class":1905,"line":2285},[1903,4181,4182],{"class":2602},"    return",[1903,4184,4185],{"class":2037}," { authenticated: ",[1903,4187,4188],{"class":2602},"!!",[1903,4190,4191],{"class":2037},"user?.id, user };\n",[1903,4193,4194,4197,4199],{"class":1905,"line":2297},[1903,4195,4196],{"class":2037},"  } ",[1903,4198,2845],{"class":2602},[1903,4200,4201],{"class":2037}," (error) {\n",[1903,4203,4204,4207,4210,4212,4215],{"class":1905,"line":2302},[1903,4205,4206],{"class":2037},"    console.",[1903,4208,4209],{"class":1909},"error",[1903,4211,2656],{"class":2037},[1903,4213,4214],{"class":1913},"\"Error checking authentication:\"",[1903,4216,4217],{"class":2037},", error);\n",[1903,4219,4220,4222,4224,4227,4230,4233],{"class":1905,"line":2351},[1903,4221,4182],{"class":2602},[1903,4223,4185],{"class":2037},[1903,4225,4226],{"class":2046},"false",[1903,4228,4229],{"class":2037},", user: ",[1903,4231,4232],{"class":2046},"null",[1903,4234,4235],{"class":2037}," };\n",[1903,4237,4238],{"class":1905,"line":2359},[1903,4239,2877],{"class":2037},[1903,4241,4242],{"class":1905,"line":2364},[1903,4243,4244],{"class":2037},"};\n",[1844,4246,4247,4248,4251],{},"The code snippet above makes a request using ",[1890,4249,4250],{},"client.request(readMe())"," to try to get the current user's information\nand checks if that request returns a user with an ID. It also returns whether authentication was successful based on whether that user data exists.",[1933,4253,4255],{"id":4254},"refreshing-tokens","Refreshing Tokens",[1844,4257,4258,4259,4262],{},"As access tokens expire after a set time period, you'll need to refresh them and that's where the ",[1890,4260,4261],{},"refreshAccessToken"," function comes in. It will handle token renewal for both cookie-based and JSON-based authentication modes.",[1844,4264,4265,4266,4269],{},"Add this function right after the ",[1890,4267,4268],{},"isAuthentcated"," function:",[1895,4271,4273],{"className":2588,"code":4272,"language":2590,"meta":24,"style":24},"// src/lib/directus.js\n\nimport { refresh } from \"@directus/sdk\";\n\nexport const refreshToken = async (mode = \"json\", refreshToken = null) => {\n  try {\n    let result;\n\n    if (mode === \"json\" && refreshToken) {\n     \n      result = await client.request({ mode: \"json\", refreshToken }));\n    } else if (mode === \"cookie\") {\n      // Use cookie-based refresh\n      result = await client.request(refresh({ mode: \"cookie\" }));\n    } else {\n      result = await client.refresh();\n    }\n\n    console.log(\"Token refreshed successfully\");\n    return {\n      access_token: result.access_token,\n      expires: result.expires,\n      refresh_token: result.refresh_token,\n    };\n  } catch (error) {\n    console.error(\"Token refresh failed:\", error);\n    throw error;\n  }\n};\n",[1890,4274,4275,4279,4283,4296,4300,4343,4349,4357,4361,4380,4385,4406,4426,4431,4455,4463,4477,4481,4485,4499,4505,4510,4515,4520,4525,4533,4546,4554,4558],{"__ignoreMap":24},[1903,4276,4277],{"class":1905,"line":1906},[1903,4278,2597],{"class":2178},[1903,4280,4281],{"class":1905,"line":1917},[1903,4282,2699],{"emptyLinePlaceholder":2698},[1903,4284,4285,4287,4290,4292,4294],{"class":1905,"line":1926},[1903,4286,2603],{"class":2602},[1903,4288,4289],{"class":2037}," { refresh } ",[1903,4291,2609],{"class":2602},[1903,4293,2612],{"class":1913},[1903,4295,2615],{"class":2037},[1903,4297,4298],{"class":1905,"line":2235},[1903,4299,2699],{"emptyLinePlaceholder":2698},[1903,4301,4302,4304,4306,4309,4311,4313,4316,4320,4322,4325,4328,4331,4333,4336,4339,4341],{"class":1905,"line":2247},[1903,4303,2636],{"class":2602},[1903,4305,2639],{"class":2602},[1903,4307,4308],{"class":1909}," refreshToken",[1903,4310,2626],{"class":2602},[1903,4312,4138],{"class":2602},[1903,4314,4315],{"class":2037}," (",[1903,4317,4319],{"class":4318},"sP4rz","mode",[1903,4321,2626],{"class":2602},[1903,4323,4324],{"class":1913}," \"json\"",[1903,4326,4327],{"class":2037},", ",[1903,4329,4330],{"class":4318},"refreshToken",[1903,4332,2626],{"class":2602},[1903,4334,4335],{"class":2046}," null",[1903,4337,4338],{"class":2037},") ",[1903,4340,4144],{"class":2602},[1903,4342,4147],{"class":2037},[1903,4344,4345,4347],{"class":1905,"line":2252},[1903,4346,4152],{"class":2602},[1903,4348,4147],{"class":2037},[1903,4350,4351,4354],{"class":1905,"line":2272},[1903,4352,4353],{"class":2602},"    let",[1903,4355,4356],{"class":2037}," result;\n",[1903,4358,4359],{"class":1905,"line":2280},[1903,4360,2699],{"emptyLinePlaceholder":2698},[1903,4362,4363,4366,4369,4372,4374,4377],{"class":1905,"line":2285},[1903,4364,4365],{"class":2602},"    if",[1903,4367,4368],{"class":2037}," (mode ",[1903,4370,4371],{"class":2602},"===",[1903,4373,4324],{"class":1913},[1903,4375,4376],{"class":2602}," &&",[1903,4378,4379],{"class":2037}," refreshToken) {\n",[1903,4381,4382],{"class":1905,"line":2297},[1903,4383,4384],{"class":2037},"     \n",[1903,4386,4387,4390,4392,4394,4396,4398,4401,4403],{"class":1905,"line":2302},[1903,4388,4389],{"class":2037},"      result ",[1903,4391,2773],{"class":2602},[1903,4393,2776],{"class":2602},[1903,4395,2779],{"class":2037},[1903,4397,2782],{"class":1909},[1903,4399,4400],{"class":2037},"({ mode: ",[1903,4402,3977],{"class":1913},[1903,4404,4405],{"class":2037},", refreshToken }));\n",[1903,4407,4408,4410,4413,4416,4418,4420,4423],{"class":1905,"line":2351},[1903,4409,2842],{"class":2037},[1903,4411,4412],{"class":2602},"else",[1903,4414,4415],{"class":2602}," if",[1903,4417,4368],{"class":2037},[1903,4419,4371],{"class":2602},[1903,4421,4422],{"class":1913}," \"cookie\"",[1903,4424,4425],{"class":2037},") {\n",[1903,4427,4428],{"class":1905,"line":2359},[1903,4429,4430],{"class":2178},"      // Use cookie-based refresh\n",[1903,4432,4433,4435,4437,4439,4441,4443,4445,4448,4450,4452],{"class":1905,"line":2364},[1903,4434,4389],{"class":2037},[1903,4436,2773],{"class":2602},[1903,4438,2776],{"class":2602},[1903,4440,2779],{"class":2037},[1903,4442,2782],{"class":1909},[1903,4444,2656],{"class":2037},[1903,4446,4447],{"class":1909},"refresh",[1903,4449,4400],{"class":2037},[1903,4451,4063],{"class":1913},[1903,4453,4454],{"class":2037}," }));\n",[1903,4456,4457,4459,4461],{"class":1905,"line":2396},[1903,4458,2842],{"class":2037},[1903,4460,4412],{"class":2602},[1903,4462,4147],{"class":2037},[1903,4464,4465,4467,4469,4471,4473,4475],{"class":1905,"line":2404},[1903,4466,4389],{"class":2037},[1903,4468,2773],{"class":2602},[1903,4470,2776],{"class":2602},[1903,4472,2779],{"class":2037},[1903,4474,4447],{"class":1909},[1903,4476,3461],{"class":2037},[1903,4478,4479],{"class":1905,"line":2409},[1903,4480,2871],{"class":2037},[1903,4482,4483],{"class":1905,"line":2423},[1903,4484,2699],{"emptyLinePlaceholder":2698},[1903,4486,4487,4489,4492,4494,4497],{"class":1905,"line":2428},[1903,4488,4206],{"class":2037},[1903,4490,4491],{"class":1909},"log",[1903,4493,2656],{"class":2037},[1903,4495,4496],{"class":1913},"\"Token refreshed successfully\"",[1903,4498,2837],{"class":2037},[1903,4500,4501,4503],{"class":1905,"line":2444},[1903,4502,4182],{"class":2602},[1903,4504,4147],{"class":2037},[1903,4506,4507],{"class":1905,"line":2452},[1903,4508,4509],{"class":2037},"      access_token: result.access_token,\n",[1903,4511,4512],{"class":1905,"line":2469},[1903,4513,4514],{"class":2037},"      expires: result.expires,\n",[1903,4516,4517],{"class":1905,"line":2510},[1903,4518,4519],{"class":2037},"      refresh_token: result.refresh_token,\n",[1903,4521,4522],{"class":1905,"line":2851},[1903,4523,4524],{"class":2037},"    };\n",[1903,4526,4527,4529,4531],{"class":1905,"line":2862},[1903,4528,4196],{"class":2037},[1903,4530,2845],{"class":2602},[1903,4532,4201],{"class":2037},[1903,4534,4535,4537,4539,4541,4544],{"class":1905,"line":2868},[1903,4536,4206],{"class":2037},[1903,4538,4209],{"class":1909},[1903,4540,2656],{"class":2037},[1903,4542,4543],{"class":1913},"\"Token refresh failed:\"",[1903,4545,4217],{"class":2037},[1903,4547,4548,4551],{"class":1905,"line":2874},[1903,4549,4550],{"class":2602},"    throw",[1903,4552,4553],{"class":2037}," error;\n",[1903,4555,4556],{"class":1905,"line":2880},[1903,4557,2877],{"class":2037},[1903,4559,4560],{"class":1905,"line":2890},[1903,4561,4244],{"class":2037},[1844,4563,4564],{},"The code above uses the provided refresh token to explicitly request a new access token for json mode while it handles refresh through cookies without needing an explicit refresh token for cookie mode.",[1933,4566,4568],{"id":4567},"create-the-protected-page","Create the Protected Page",[1844,4570,4571,4572,4574,4575,4578,4579,4581],{},"Create a subdirectory inside the ",[1890,4573,2678],{}," directory called ",[1890,4576,4577],{},"protected",". Inside this directory, create a ",[1890,4580,2682],{}," inside it.",[1844,4583,4584],{},"Add the following code:",[1895,4586,4588],{"className":2588,"code":4587,"language":2590,"meta":24,"style":24},"// src/routes/protected/+page.svelte\n\n\u003Cscript>\n import { onMount } from \"svelte\";\n import { isAuthenticated, logoutUser } from \"../../lib/directus.js\";\n import { goto } from \"$app/navigation\";\n\n onMount(async () => {\n   console.log(\"onMount\");\n   const isAuth = await isAuthenticated();\n   console.log(\"isAuth\", isAuth);\n\n   if (isAuth.authenticated === false) {\n     goto(\"/login\");\n   }\n });\n\n const handleLogout = async () => {\n   try {\n     await logoutUser(); \n     goto(\"/login\"); \n   } catch (error) {\n     console.error(\"Logout failed:\", error);\n   }\n };\n\u003C/script>\n\n\u003Ch1>Protected Page\u003C/h1>\n\u003Cp>Welcome! You are logged in.\u003C/p>\n\n\u003Cnav>\n \u003Ca href=\"/protected/posts\" class=\"nav-link\">View Posts\u003C/a>\n \u003Ca href=\"/protected/posts/create\" class=\"nav-link\">Create New Posts\u003C/a>\n \u003Ca href=\"/protected/profile\" class=\"nav-link\">Profile\u003C/a>\n\u003C/nav>\n\n\u003Cbutton on:click={handleLogout}>Logout\u003C/button>\n",[1890,4589,4590,4595,4599,4607,4612,4617,4622,4626,4631,4645,4658,4672,4676,4691,4702,4707,4712,4716,4721,4726,4737,4748,4757,4767,4771,4775,4783,4787,4800,4813,4817,4826,4854,4880,4906,4914,4918],{"__ignoreMap":24},[1903,4591,4592],{"class":1905,"line":1906},[1903,4593,4594],{"class":2178},"// src/routes/protected/+page.svelte\n",[1903,4596,4597],{"class":1905,"line":1917},[1903,4598,2699],{"emptyLinePlaceholder":2698},[1903,4600,4601,4603,4605],{"class":1905,"line":1926},[1903,4602,2704],{"class":2037},[1903,4604,2708],{"class":2707},[1903,4606,2711],{"class":2037},[1903,4608,4609],{"class":1905,"line":2235},[1903,4610,4611],{"class":2037}," import { onMount } from \"svelte\";\n",[1903,4613,4614],{"class":1905,"line":2247},[1903,4615,4616],{"class":2037}," import { isAuthenticated, logoutUser } from \"../../lib/directus.js\";\n",[1903,4618,4619],{"class":1905,"line":2252},[1903,4620,4621],{"class":2037}," import { goto } from \"$app/navigation\";\n",[1903,4623,4624],{"class":1905,"line":2272},[1903,4625,2699],{"emptyLinePlaceholder":2698},[1903,4627,4628],{"class":1905,"line":2280},[1903,4629,4630],{"class":2037}," onMount(async () => {\n",[1903,4632,4633,4636,4638,4640,4643],{"class":1905,"line":2285},[1903,4634,4635],{"class":2037},"   console.",[1903,4637,4491],{"class":1909},[1903,4639,2656],{"class":2037},[1903,4641,4642],{"class":1913},"\"onMount\"",[1903,4644,2837],{"class":2037},[1903,4646,4647,4650,4652,4654,4656],{"class":1905,"line":2297},[1903,4648,4649],{"class":2037},"   const isAuth ",[1903,4651,2773],{"class":2602},[1903,4653,2776],{"class":2602},[1903,4655,3458],{"class":1909},[1903,4657,3461],{"class":2037},[1903,4659,4660,4662,4664,4666,4669],{"class":1905,"line":2302},[1903,4661,4635],{"class":2037},[1903,4663,4491],{"class":1909},[1903,4665,2656],{"class":2037},[1903,4667,4668],{"class":1913},"\"isAuth\"",[1903,4670,4671],{"class":2037},", isAuth);\n",[1903,4673,4674],{"class":1905,"line":2351},[1903,4675,2699],{"emptyLinePlaceholder":2698},[1903,4677,4678,4681,4684,4686,4689],{"class":1905,"line":2359},[1903,4679,4680],{"class":1909},"   if",[1903,4682,4683],{"class":2037}," (isAuth.authenticated ",[1903,4685,4371],{"class":2602},[1903,4687,4688],{"class":2046}," false",[1903,4690,4425],{"class":2037},[1903,4692,4693,4696,4698,4700],{"class":1905,"line":2364},[1903,4694,4695],{"class":1909},"     goto",[1903,4697,2656],{"class":2037},[1903,4699,2834],{"class":1913},[1903,4701,2837],{"class":2037},[1903,4703,4704],{"class":1905,"line":2396},[1903,4705,4706],{"class":2037},"   }\n",[1903,4708,4709],{"class":1905,"line":2404},[1903,4710,4711],{"class":2037}," });\n",[1903,4713,4714],{"class":1905,"line":2409},[1903,4715,2699],{"emptyLinePlaceholder":2698},[1903,4717,4718],{"class":1905,"line":2423},[1903,4719,4720],{"class":2037}," const handleLogout = async () => {\n",[1903,4722,4723],{"class":1905,"line":2428},[1903,4724,4725],{"class":2037},"   try {\n",[1903,4727,4728,4731,4734],{"class":1905,"line":2444},[1903,4729,4730],{"class":2037},"     await ",[1903,4732,4733],{"class":1909},"logoutUser",[1903,4735,4736],{"class":2037},"(); \n",[1903,4738,4739,4741,4743,4745],{"class":1905,"line":2452},[1903,4740,4695],{"class":1909},[1903,4742,2656],{"class":2037},[1903,4744,2834],{"class":1913},[1903,4746,4747],{"class":2037},"); \n",[1903,4749,4750,4753,4755],{"class":1905,"line":2469},[1903,4751,4752],{"class":2037},"   } ",[1903,4754,2845],{"class":1909},[1903,4756,4201],{"class":2037},[1903,4758,4759,4762,4765],{"class":1905,"line":2510},[1903,4760,4761],{"class":2037},"     console.error(",[1903,4763,4764],{"class":1913},"\"Logout failed:\"",[1903,4766,4217],{"class":2037},[1903,4768,4769],{"class":1905,"line":2851},[1903,4770,4706],{"class":2037},[1903,4772,4773],{"class":1905,"line":2862},[1903,4774,4235],{"class":2037},[1903,4776,4777,4779,4781],{"class":1905,"line":2868},[1903,4778,2883],{"class":2037},[1903,4780,2708],{"class":2707},[1903,4782,2711],{"class":2037},[1903,4784,4785],{"class":1905,"line":2874},[1903,4786,2699],{"emptyLinePlaceholder":2698},[1903,4788,4789,4791,4793,4796,4798],{"class":1905,"line":2880},[1903,4790,2704],{"class":2037},[1903,4792,2919],{"class":2707},[1903,4794,4795],{"class":2037},">Protected Page\u003C/",[1903,4797,2919],{"class":2707},[1903,4799,2711],{"class":2037},[1903,4801,4802,4804,4806,4809,4811],{"class":1905,"line":2890},[1903,4803,2704],{"class":2037},[1903,4805,1844],{"class":2707},[1903,4807,4808],{"class":2037},">Welcome! You are logged in.\u003C/",[1903,4810,1844],{"class":2707},[1903,4812,2711],{"class":2037},[1903,4814,4815],{"class":1905,"line":2895},[1903,4816,2699],{"emptyLinePlaceholder":2698},[1903,4818,4819,4821,4824],{"class":1905,"line":2913},[1903,4820,2704],{"class":2037},[1903,4822,4823],{"class":2707},"nav",[1903,4825,2711],{"class":2037},[1903,4827,4828,4831,4833,4835,4837,4840,4842,4844,4847,4850,4852],{"class":1905,"line":2929},[1903,4829,4830],{"class":2037}," \u003C",[1903,4832,1862],{"class":2707},[1903,4834,3278],{"class":1909},[1903,4836,2773],{"class":2602},[1903,4838,4839],{"class":1913},"\"/protected/posts\"",[1903,4841,2903],{"class":1909},[1903,4843,2773],{"class":2602},[1903,4845,4846],{"class":1913},"\"nav-link\"",[1903,4848,4849],{"class":2037},">View Posts\u003C/",[1903,4851,1862],{"class":2707},[1903,4853,2711],{"class":2037},[1903,4855,4856,4858,4860,4862,4864,4867,4869,4871,4873,4876,4878],{"class":1905,"line":2934},[1903,4857,4830],{"class":2037},[1903,4859,1862],{"class":2707},[1903,4861,3278],{"class":1909},[1903,4863,2773],{"class":2602},[1903,4865,4866],{"class":1913},"\"/protected/posts/create\"",[1903,4868,2903],{"class":1909},[1903,4870,2773],{"class":2602},[1903,4872,4846],{"class":1913},[1903,4874,4875],{"class":2037},">Create New Posts\u003C/",[1903,4877,1862],{"class":2707},[1903,4879,2711],{"class":2037},[1903,4881,4882,4884,4886,4888,4890,4893,4895,4897,4899,4902,4904],{"class":1905,"line":2940},[1903,4883,4830],{"class":2037},[1903,4885,1862],{"class":2707},[1903,4887,3278],{"class":1909},[1903,4889,2773],{"class":2602},[1903,4891,4892],{"class":1913},"\"/protected/profile\"",[1903,4894,2903],{"class":1909},[1903,4896,2773],{"class":2602},[1903,4898,4846],{"class":1913},[1903,4900,4901],{"class":2037},">Profile\u003C/",[1903,4903,1862],{"class":2707},[1903,4905,2711],{"class":2037},[1903,4907,4908,4910,4912],{"class":1905,"line":2962},[1903,4909,2883],{"class":2037},[1903,4911,4823],{"class":2707},[1903,4913,2711],{"class":2037},[1903,4915,4916],{"class":1905,"line":2974},[1903,4917,2699],{"emptyLinePlaceholder":2698},[1903,4919,4920,4922,4924,4927,4929,4932,4934,4937,4939],{"class":1905,"line":2979},[1903,4921,2704],{"class":2037},[1903,4923,3227],{"class":2707},[1903,4925,4926],{"class":1909}," on",[1903,4928,2047],{"class":2037},[1903,4930,4931],{"class":1909},"click",[1903,4933,2773],{"class":2602},[1903,4935,4936],{"class":2037},"{handleLogout}>Logout\u003C/",[1903,4938,3227],{"class":2707},[1903,4940,2711],{"class":2037},[1844,4942,4943],{},"This page contains the navigation links to other protected resources and a logout button.",[1933,4945,4947],{"id":4946},"create-the-profile-page","Create the Profile Page",[1844,4949,4950,4951,4954,4955,4958,4959,4961],{},"Create a subdirectory called ",[1890,4952,4953],{},"profile"," inside the  ",[1890,4956,4957],{},"./src/routes/protected"," directory and create a ",[1890,4960,2682],{}," file inside it with the following contents:",[1895,4963,4965],{"className":2588,"code":4964,"language":2590,"meta":24,"style":24},"// src/routes/protected/profile/+page.svelte\n\u003Cscript>\n  import { client, isAuthenticated } from \"../../../lib/directus.js\";\n  import { readMe, updateMe } from \"@directus/sdk\";\n  import { onMount } from \"svelte\";\n  import { goto } from \"$app/navigation\";\n\n  let userData = null;\n  let isEditing = false;\n  let formData = {};\n  let message = \"\";\n\n  onMount(async () => {\n    console.log(\"onMount\");\n\n    // Check if the user is authenticated\n    const isAuth = await isAuthenticated();\n    console.log(\"isAuth\", isAuth);\n\n    if (isAuth.authenticated === false) {\n      goto(\"/login\"); \n      return;\n    }\n\n    // Fetch user profile data using Directus SDK\n    try {\n      const response = await client.request(readMe());\n      console.log(\"ress>>>\", response);\n      userData = {\n        id: response.id,\n        firstName: response.first_name,\n        lastName: response.last_name,\n        email: response.email,\n      };\n      console.log(\"userData>>>>>>\", userData);\n      formData = { ...userData };\n    } catch (error) {\n      console.error(\"Failed to fetch user data:\", error);\n      goto(\"/login\"); \n    }\n  });\n\n  async function handleSubmit() {\n    console.log(\"formData>>>>>>\", formData);\n    try {\n      const response = await client.request(\n        updateMe({\n          first_name: formData.firstName,\n          last_name: formData.lastName,\n          email: formData.email,\n        })\n      );\n      console.log(\"response>>>>>>\", response);\n      message = \"Profile updated successfully!\";\n      isEditing = false;\n      userData = { ...formData };\n    } catch (error) {\n      console.error(\"Error updating profile:\", error);\n      message = \"Failed to update profile. Please try again.\";\n    }\n  }\n\u003C/script>\n\n\u003Cdiv class=\"container\">\n  \u003Ch1 class=\"title\">Profile\u003C/h1>\n\n  {#if message}\n    \u003Cdiv class=\"message\">{message}\u003C/div>\n  {/if}\n\n  {#if userData}\n    {#if isEditing}\n      \u003Cform on:submit|preventDefault={handleSubmit}>\n        \u003Cdiv class=\"form-group\">\n          \u003Clabel for=\"first_name\">First Name\u003C/label>\n          \u003Cinput type=\"text\" id=\"first_name\" bind:value={formData.firstName} />\n        \u003C/div>\n\n        \u003Cdiv class=\"form-group\">\n          \u003Clabel for=\"last_name\">Last Name\u003C/label>\n          \u003Cinput type=\"text\" id=\"last_name\" bind:value={formData.lastName} />\n        \u003C/div>\n\n        \u003Cdiv class=\"form-group\">\n          \u003Clabel for=\"email\">Email\u003C/label>\n          \u003Cinput type=\"email\" id=\"email\" bind:value={formData.email} />\n        \u003C/div>\n\n        \u003Cbutton type=\"submit\" class=\"primary\">Save\u003C/button>\n        \u003Cbutton\n          type=\"button\"\n          class=\"secondary\"\n          on:click={() => {\n            isEditing = false;\n            formData = { ...userData };\n          }}\n        >\n          Cancel\n        \u003C/button>\n      \u003C/form>\n    {:else}\n      \u003Cdiv class=\"profile-info\">\n        \u003Cdiv class=\"profile-field\">\n          \u003Cspan class=\"field-label\">First Name\u003C/span>\n          \u003Cspan style=\"color: #000;\">{userData?.firstName || \"Not set\"}\u003C/span>\n        \u003C/div>\n        \u003Cdiv class=\"profile-field\">\n          \u003Cspan class=\"field-label\">Last Name\u003C/span>\n          \u003Cspan style=\"color: #000;\">{userData.lastName || \"Not set\"}\u003C/span>\n        \u003C/div>\n        \u003Cdiv class=\"profile-field\">\n          \u003Cspan class=\"field-label\">Email\u003C/span>\n          \u003Cspan style=\"color: #000;\">{userData.email}\u003C/span>\n        \u003C/div>\n        \u003Cbutton class=\"primary\" on:click={() => (isEditing = true)}>\n          Edit Profile\n        \u003C/button>\n      \u003C/div>\n    {/if}\n  {:else}\n    \u003Cdiv class=\"loading\">Loading...\u003C/div>\n  {/if}\n\u003C/div>\n",[1890,4966,4967,4972,4980,4985,4990,4995,4999,5003,5008,5013,5018,5023,5027,5032,5044,5048,5053,5066,5078,5082,5094,5104,5109,5113,5117,5122,5126,5144,5153,5162,5167,5172,5177,5182,5187,5197,5213,5221,5230,5240,5244,5249,5253,5258,5272,5276,5290,5298,5303,5308,5313,5317,5321,5330,5342,5353,5366,5374,5383,5394,5398,5402,5410,5414,5428,5447,5451,5456,5476,5484,5489,5495,5501,5511,5525,5549,5581,5591,5596,5612,5633,5663,5672,5677,5692,5712,5742,5751,5756,5783,5791,5802,5813,5832,5844,5858,5864,5870,5876,5885,5895,5905,5921,5937,5957,5985,5994,6009,6028,6054,6063,6078,6097,6117,6126,6162,6168,6177,6186,6197,6207,6228,6237],{"__ignoreMap":24},[1903,4968,4969],{"class":1905,"line":1906},[1903,4970,4971],{"class":2178},"// src/routes/protected/profile/+page.svelte\n",[1903,4973,4974,4976,4978],{"class":1905,"line":1917},[1903,4975,2704],{"class":2037},[1903,4977,2708],{"class":2707},[1903,4979,2711],{"class":2037},[1903,4981,4982],{"class":1905,"line":1926},[1903,4983,4984],{"class":2037},"  import { client, isAuthenticated } from \"../../../lib/directus.js\";\n",[1903,4986,4987],{"class":1905,"line":2235},[1903,4988,4989],{"class":2037},"  import { readMe, updateMe } from \"@directus/sdk\";\n",[1903,4991,4992],{"class":1905,"line":2247},[1903,4993,4994],{"class":2037},"  import { onMount } from \"svelte\";\n",[1903,4996,4997],{"class":1905,"line":2252},[1903,4998,2726],{"class":2037},[1903,5000,5001],{"class":1905,"line":2272},[1903,5002,2699],{"emptyLinePlaceholder":2698},[1903,5004,5005],{"class":1905,"line":2280},[1903,5006,5007],{"class":2037},"  let userData = null;\n",[1903,5009,5010],{"class":1905,"line":2285},[1903,5011,5012],{"class":2037},"  let isEditing = false;\n",[1903,5014,5015],{"class":1905,"line":2297},[1903,5016,5017],{"class":2037},"  let formData = {};\n",[1903,5019,5020],{"class":1905,"line":2302},[1903,5021,5022],{"class":2037},"  let message = \"\";\n",[1903,5024,5025],{"class":1905,"line":2351},[1903,5026,2699],{"emptyLinePlaceholder":2698},[1903,5028,5029],{"class":1905,"line":2359},[1903,5030,5031],{"class":2037},"  onMount(async () => {\n",[1903,5033,5034,5036,5038,5040,5042],{"class":1905,"line":2364},[1903,5035,4206],{"class":2037},[1903,5037,4491],{"class":1909},[1903,5039,2656],{"class":2037},[1903,5041,4642],{"class":1913},[1903,5043,2837],{"class":2037},[1903,5045,5046],{"class":1905,"line":2396},[1903,5047,2699],{"emptyLinePlaceholder":2698},[1903,5049,5050],{"class":1905,"line":2404},[1903,5051,5052],{"class":2178},"    // Check if the user is authenticated\n",[1903,5054,5055,5058,5060,5062,5064],{"class":1905,"line":2409},[1903,5056,5057],{"class":2037},"    const isAuth ",[1903,5059,2773],{"class":2602},[1903,5061,2776],{"class":2602},[1903,5063,3458],{"class":1909},[1903,5065,3461],{"class":2037},[1903,5067,5068,5070,5072,5074,5076],{"class":1905,"line":2423},[1903,5069,4206],{"class":2037},[1903,5071,4491],{"class":1909},[1903,5073,2656],{"class":2037},[1903,5075,4668],{"class":1913},[1903,5077,4671],{"class":2037},[1903,5079,5080],{"class":1905,"line":2428},[1903,5081,2699],{"emptyLinePlaceholder":2698},[1903,5083,5084,5086,5088,5090,5092],{"class":1905,"line":2444},[1903,5085,4365],{"class":1909},[1903,5087,4683],{"class":2037},[1903,5089,4371],{"class":2602},[1903,5091,4688],{"class":2046},[1903,5093,4425],{"class":2037},[1903,5095,5096,5098,5100,5102],{"class":1905,"line":2452},[1903,5097,2829],{"class":1909},[1903,5099,2656],{"class":2037},[1903,5101,2834],{"class":1913},[1903,5103,4747],{"class":2037},[1903,5105,5106],{"class":1905,"line":2469},[1903,5107,5108],{"class":2037},"      return;\n",[1903,5110,5111],{"class":1905,"line":2510},[1903,5112,2871],{"class":2037},[1903,5114,5115],{"class":1905,"line":2851},[1903,5116,2699],{"emptyLinePlaceholder":2698},[1903,5118,5119],{"class":1905,"line":2862},[1903,5120,5121],{"class":2178},"    // Fetch user profile data using Directus SDK\n",[1903,5123,5124],{"class":1905,"line":2868},[1903,5125,2765],{"class":2037},[1903,5127,5128,5130,5132,5134,5136,5138,5140,5142],{"class":1905,"line":2874},[1903,5129,2770],{"class":2037},[1903,5131,2773],{"class":2602},[1903,5133,2776],{"class":2602},[1903,5135,2779],{"class":2037},[1903,5137,2782],{"class":1909},[1903,5139,2656],{"class":2037},[1903,5141,4175],{"class":1909},[1903,5143,2662],{"class":2037},[1903,5145,5146,5148,5151],{"class":1905,"line":2880},[1903,5147,2818],{"class":2037},[1903,5149,5150],{"class":1913},"\"ress>>>\"",[1903,5152,2824],{"class":2037},[1903,5154,5155,5158,5160],{"class":1905,"line":2890},[1903,5156,5157],{"class":2037},"      userData ",[1903,5159,2773],{"class":2602},[1903,5161,4147],{"class":2037},[1903,5163,5164],{"class":1905,"line":2895},[1903,5165,5166],{"class":2037},"        id: response.id,\n",[1903,5168,5169],{"class":1905,"line":2913},[1903,5170,5171],{"class":2037},"        firstName: response.first_name,\n",[1903,5173,5174],{"class":1905,"line":2929},[1903,5175,5176],{"class":2037},"        lastName: response.last_name,\n",[1903,5178,5179],{"class":1905,"line":2934},[1903,5180,5181],{"class":2037},"        email: response.email,\n",[1903,5183,5184],{"class":1905,"line":2940},[1903,5185,5186],{"class":2037},"      };\n",[1903,5188,5189,5191,5194],{"class":1905,"line":2962},[1903,5190,2818],{"class":2037},[1903,5192,5193],{"class":1913},"\"userData>>>>>>\"",[1903,5195,5196],{"class":2037},", userData);\n",[1903,5198,5199,5202,5204,5207,5210],{"class":1905,"line":2974},[1903,5200,5201],{"class":2037},"      formData ",[1903,5203,2773],{"class":2602},[1903,5205,5206],{"class":2037}," { ",[1903,5208,5209],{"class":2602},"...",[1903,5211,5212],{"class":2037},"userData };\n",[1903,5214,5215,5217,5219],{"class":1905,"line":2979},[1903,5216,2842],{"class":2037},[1903,5218,2845],{"class":1909},[1903,5220,4201],{"class":2037},[1903,5222,5223,5225,5228],{"class":1905,"line":2991},[1903,5224,3573],{"class":2037},[1903,5226,5227],{"class":1913},"\"Failed to fetch user data:\"",[1903,5229,4217],{"class":2037},[1903,5231,5232,5234,5236,5238],{"class":1905,"line":3006},[1903,5233,2829],{"class":1909},[1903,5235,2656],{"class":2037},[1903,5237,2834],{"class":1913},[1903,5239,4747],{"class":2037},[1903,5241,5242],{"class":1905,"line":3015},[1903,5243,2871],{"class":2037},[1903,5245,5246],{"class":1905,"line":3026},[1903,5247,5248],{"class":2037},"  });\n",[1903,5250,5251],{"class":1905,"line":3042},[1903,5252,2699],{"emptyLinePlaceholder":2698},[1903,5254,5255],{"class":1905,"line":3053},[1903,5256,5257],{"class":2037},"  async function handleSubmit() {\n",[1903,5259,5260,5262,5264,5266,5269],{"class":1905,"line":3059},[1903,5261,4206],{"class":2037},[1903,5263,4491],{"class":1909},[1903,5265,2656],{"class":2037},[1903,5267,5268],{"class":1913},"\"formData>>>>>>\"",[1903,5270,5271],{"class":2037},", formData);\n",[1903,5273,5274],{"class":1905,"line":3065},[1903,5275,2765],{"class":2037},[1903,5277,5278,5280,5282,5284,5286,5288],{"class":1905,"line":3072},[1903,5279,2770],{"class":2037},[1903,5281,2773],{"class":2602},[1903,5283,2776],{"class":2602},[1903,5285,2779],{"class":2037},[1903,5287,2782],{"class":1909},[1903,5289,2785],{"class":2037},[1903,5291,5292,5295],{"class":1905,"line":3081},[1903,5293,5294],{"class":1909},"        updateMe",[1903,5296,5297],{"class":2037},"({\n",[1903,5299,5300],{"class":1905,"line":3095},[1903,5301,5302],{"class":2037},"          first_name: formData.firstName,\n",[1903,5304,5305],{"class":1905,"line":3105},[1903,5306,5307],{"class":2037},"          last_name: formData.lastName,\n",[1903,5309,5310],{"class":1905,"line":3110},[1903,5311,5312],{"class":2037},"          email: formData.email,\n",[1903,5314,5315],{"class":1905,"line":3115},[1903,5316,2808],{"class":2037},[1903,5318,5319],{"class":1905,"line":3125},[1903,5320,2813],{"class":2037},[1903,5322,5323,5325,5328],{"class":1905,"line":3166},[1903,5324,2818],{"class":2037},[1903,5326,5327],{"class":1913},"\"response>>>>>>\"",[1903,5329,2824],{"class":2037},[1903,5331,5332,5335,5337,5340],{"class":1905,"line":3173},[1903,5333,5334],{"class":2037},"      message ",[1903,5336,2773],{"class":2602},[1903,5338,5339],{"class":1913}," \"Profile updated successfully!\"",[1903,5341,2615],{"class":2037},[1903,5343,5344,5347,5349,5351],{"class":1905,"line":3184},[1903,5345,5346],{"class":2037},"      isEditing ",[1903,5348,2773],{"class":2602},[1903,5350,4688],{"class":2046},[1903,5352,2615],{"class":2037},[1903,5354,5355,5357,5359,5361,5363],{"class":1905,"line":3199},[1903,5356,5157],{"class":2037},[1903,5358,2773],{"class":2602},[1903,5360,5206],{"class":2037},[1903,5362,5209],{"class":2602},[1903,5364,5365],{"class":2037},"formData };\n",[1903,5367,5368,5370,5372],{"class":1905,"line":3210},[1903,5369,2842],{"class":2037},[1903,5371,2845],{"class":1909},[1903,5373,4201],{"class":2037},[1903,5375,5376,5378,5381],{"class":1905,"line":3216},[1903,5377,3573],{"class":2037},[1903,5379,5380],{"class":1913},"\"Error updating profile:\"",[1903,5382,4217],{"class":2037},[1903,5384,5385,5387,5389,5392],{"class":1905,"line":3222},[1903,5386,5334],{"class":2037},[1903,5388,2773],{"class":2602},[1903,5390,5391],{"class":1913}," \"Failed to update profile. Please try again.\"",[1903,5393,2615],{"class":2037},[1903,5395,5396],{"class":1905,"line":3244},[1903,5397,2871],{"class":2037},[1903,5399,5400],{"class":1905,"line":3254},[1903,5401,2877],{"class":2037},[1903,5403,5404,5406,5408],{"class":1905,"line":3270},[1903,5405,2883],{"class":2037},[1903,5407,2708],{"class":2707},[1903,5409,2711],{"class":2037},[1903,5411,5412],{"class":1905,"line":3292},[1903,5413,2699],{"emptyLinePlaceholder":2698},[1903,5415,5416,5418,5420,5422,5424,5426],{"class":1905,"line":3301},[1903,5417,2704],{"class":2037},[1903,5419,2900],{"class":2707},[1903,5421,2903],{"class":1909},[1903,5423,2773],{"class":2602},[1903,5425,2908],{"class":1913},[1903,5427,2711],{"class":2037},[1903,5429,5430,5432,5434,5436,5438,5441,5443,5445],{"class":1905,"line":3839},[1903,5431,2916],{"class":2037},[1903,5433,2919],{"class":2707},[1903,5435,2903],{"class":1909},[1903,5437,2773],{"class":2602},[1903,5439,5440],{"class":1913},"\"title\"",[1903,5442,4901],{"class":2037},[1903,5444,2919],{"class":2707},[1903,5446,2711],{"class":2037},[1903,5448,5449],{"class":1905,"line":3844},[1903,5450,2699],{"emptyLinePlaceholder":2698},[1903,5452,5453],{"class":1905,"line":3859},[1903,5454,5455],{"class":2037},"  {#if message}\n",[1903,5457,5458,5460,5462,5464,5466,5469,5472,5474],{"class":1905,"line":3881},[1903,5459,2943],{"class":2037},[1903,5461,2900],{"class":2707},[1903,5463,2903],{"class":1909},[1903,5465,2773],{"class":2602},[1903,5467,5468],{"class":1913},"\"message\"",[1903,5470,5471],{"class":2037},">{message}\u003C/",[1903,5473,2900],{"class":2707},[1903,5475,2711],{"class":2037},[1903,5477,5478,5480,5482],{"class":1905,"line":3890},[1903,5479,2965],{"class":2037},[1903,5481,2968],{"class":2602},[1903,5483,2971],{"class":2037},[1903,5485,5487],{"class":1905,"line":5486},70,[1903,5488,2699],{"emptyLinePlaceholder":2698},[1903,5490,5492],{"class":1905,"line":5491},71,[1903,5493,5494],{"class":2037},"  {#if userData}\n",[1903,5496,5498],{"class":1905,"line":5497},72,[1903,5499,5500],{"class":2037},"    {#if isEditing}\n",[1903,5502,5504,5506,5508],{"class":1905,"line":5503},73,[1903,5505,3009],{"class":2037},[1903,5507,2984],{"class":2707},[1903,5509,5510],{"class":2987}," on:submit|preventDefault={handleSubmit}>\n",[1903,5512,5514,5517,5519,5521,5523],{"class":1905,"line":5513},74,[1903,5515,5516],{"class":2987},"        \u003Cdiv",[1903,5518,2903],{"class":1909},[1903,5520,2773],{"class":2602},[1903,5522,3001],{"class":1913},[1903,5524,2711],{"class":2037},[1903,5526,5528,5531,5534,5537,5539,5542,5545,5547],{"class":1905,"line":5527},75,[1903,5529,5530],{"class":2037},"          \u003C",[1903,5532,5533],{"class":2707},"label",[1903,5535,5536],{"class":1909}," for",[1903,5538,2773],{"class":2602},[1903,5540,5541],{"class":1913},"\"first_name\"",[1903,5543,5544],{"class":2037},">First Name\u003C/",[1903,5546,5533],{"class":2707},[1903,5548,2711],{"class":2037},[1903,5550,5552,5554,5556,5558,5560,5563,5566,5568,5570,5572,5574,5576,5578],{"class":1905,"line":5551},76,[1903,5553,5530],{"class":2037},[1903,5555,3130],{"class":2707},[1903,5557,2260],{"class":1909},[1903,5559,2773],{"class":2602},[1903,5561,5562],{"class":1913},"\"text\"",[1903,5564,5565],{"class":1909}," id",[1903,5567,2773],{"class":2602},[1903,5569,5541],{"class":1913},[1903,5571,3140],{"class":1909},[1903,5573,2047],{"class":2037},[1903,5575,3034],{"class":1909},[1903,5577,2773],{"class":2602},[1903,5579,5580],{"class":2037},"{formData.firstName} />\n",[1903,5582,5584,5587,5589],{"class":1905,"line":5583},77,[1903,5585,5586],{"class":2037},"        \u003C/",[1903,5588,2900],{"class":2707},[1903,5590,2711],{"class":2037},[1903,5592,5594],{"class":1905,"line":5593},78,[1903,5595,2699],{"emptyLinePlaceholder":2698},[1903,5597,5599,5602,5604,5606,5608,5610],{"class":1905,"line":5598},79,[1903,5600,5601],{"class":2037},"        \u003C",[1903,5603,2900],{"class":2707},[1903,5605,2903],{"class":1909},[1903,5607,2773],{"class":2602},[1903,5609,3001],{"class":1913},[1903,5611,2711],{"class":2037},[1903,5613,5615,5617,5619,5621,5623,5626,5629,5631],{"class":1905,"line":5614},80,[1903,5616,5530],{"class":2037},[1903,5618,5533],{"class":2707},[1903,5620,5536],{"class":1909},[1903,5622,2773],{"class":2602},[1903,5624,5625],{"class":1913},"\"last_name\"",[1903,5627,5628],{"class":2037},">Last Name\u003C/",[1903,5630,5533],{"class":2707},[1903,5632,2711],{"class":2037},[1903,5634,5636,5638,5640,5642,5644,5646,5648,5650,5652,5654,5656,5658,5660],{"class":1905,"line":5635},81,[1903,5637,5530],{"class":2037},[1903,5639,3130],{"class":2707},[1903,5641,2260],{"class":1909},[1903,5643,2773],{"class":2602},[1903,5645,5562],{"class":1913},[1903,5647,5565],{"class":1909},[1903,5649,2773],{"class":2602},[1903,5651,5625],{"class":1913},[1903,5653,3140],{"class":1909},[1903,5655,2047],{"class":2037},[1903,5657,3034],{"class":1909},[1903,5659,2773],{"class":2602},[1903,5661,5662],{"class":2037},"{formData.lastName} />\n",[1903,5664,5666,5668,5670],{"class":1905,"line":5665},82,[1903,5667,5586],{"class":2037},[1903,5669,2900],{"class":2707},[1903,5671,2711],{"class":2037},[1903,5673,5675],{"class":1905,"line":5674},83,[1903,5676,2699],{"emptyLinePlaceholder":2698},[1903,5678,5680,5682,5684,5686,5688,5690],{"class":1905,"line":5679},84,[1903,5681,5601],{"class":2037},[1903,5683,2900],{"class":2707},[1903,5685,2903],{"class":1909},[1903,5687,2773],{"class":2602},[1903,5689,3001],{"class":1913},[1903,5691,2711],{"class":2037},[1903,5693,5695,5697,5699,5701,5703,5705,5708,5710],{"class":1905,"line":5694},85,[1903,5696,5530],{"class":2037},[1903,5698,5533],{"class":2707},[1903,5700,5536],{"class":1909},[1903,5702,2773],{"class":2602},[1903,5704,3137],{"class":1913},[1903,5706,5707],{"class":2037},">Email\u003C/",[1903,5709,5533],{"class":2707},[1903,5711,2711],{"class":2037},[1903,5713,5715,5717,5719,5721,5723,5725,5727,5729,5731,5733,5735,5737,5739],{"class":1905,"line":5714},86,[1903,5716,5530],{"class":2037},[1903,5718,3130],{"class":2707},[1903,5720,2260],{"class":1909},[1903,5722,2773],{"class":2602},[1903,5724,3137],{"class":1913},[1903,5726,5565],{"class":1909},[1903,5728,2773],{"class":2602},[1903,5730,3137],{"class":1913},[1903,5732,3140],{"class":1909},[1903,5734,2047],{"class":2037},[1903,5736,3034],{"class":1909},[1903,5738,2773],{"class":2602},[1903,5740,5741],{"class":2037},"{formData.email} />\n",[1903,5743,5745,5747,5749],{"class":1905,"line":5744},87,[1903,5746,5586],{"class":2037},[1903,5748,2900],{"class":2707},[1903,5750,2711],{"class":2037},[1903,5752,5754],{"class":1905,"line":5753},88,[1903,5755,2699],{"emptyLinePlaceholder":2698},[1903,5757,5759,5761,5763,5765,5767,5769,5771,5773,5776,5779,5781],{"class":1905,"line":5758},89,[1903,5760,5601],{"class":2037},[1903,5762,3227],{"class":2707},[1903,5764,2260],{"class":1909},[1903,5766,2773],{"class":2602},[1903,5768,3234],{"class":1913},[1903,5770,2903],{"class":1909},[1903,5772,2773],{"class":2602},[1903,5774,5775],{"class":1913},"\"primary\"",[1903,5777,5778],{"class":2037},">Save\u003C/",[1903,5780,3227],{"class":2707},[1903,5782,2711],{"class":2037},[1903,5784,5786,5788],{"class":1905,"line":5785},90,[1903,5787,5601],{"class":2037},[1903,5789,5790],{"class":2707},"button\n",[1903,5792,5794,5797,5799],{"class":1905,"line":5793},91,[1903,5795,5796],{"class":1909},"          type",[1903,5798,2773],{"class":2602},[1903,5800,5801],{"class":1913},"\"button\"\n",[1903,5803,5805,5808,5810],{"class":1905,"line":5804},92,[1903,5806,5807],{"class":1909},"          class",[1903,5809,2773],{"class":2602},[1903,5811,5812],{"class":1913},"\"secondary\"\n",[1903,5814,5816,5819,5821,5823,5825,5828,5830],{"class":1905,"line":5815},93,[1903,5817,5818],{"class":1909},"          on",[1903,5820,2047],{"class":2037},[1903,5822,4931],{"class":1909},[1903,5824,2773],{"class":2602},[1903,5826,5827],{"class":2037},"{() ",[1903,5829,4144],{"class":2602},[1903,5831,4147],{"class":2037},[1903,5833,5835,5838,5840,5842],{"class":1905,"line":5834},94,[1903,5836,5837],{"class":2037},"            isEditing ",[1903,5839,2773],{"class":2602},[1903,5841,4688],{"class":2046},[1903,5843,2615],{"class":2037},[1903,5845,5847,5850,5852,5854,5856],{"class":1905,"line":5846},95,[1903,5848,5849],{"class":2037},"            formData ",[1903,5851,2773],{"class":2602},[1903,5853,5206],{"class":2037},[1903,5855,5209],{"class":2602},[1903,5857,5212],{"class":2037},[1903,5859,5861],{"class":1905,"line":5860},96,[1903,5862,5863],{"class":2037},"          }}\n",[1903,5865,5867],{"class":1905,"line":5866},97,[1903,5868,5869],{"class":2037},"        >\n",[1903,5871,5873],{"class":1905,"line":5872},98,[1903,5874,5875],{"class":2037},"          Cancel\n",[1903,5877,5879,5881,5883],{"class":1905,"line":5878},99,[1903,5880,5586],{"class":2037},[1903,5882,3227],{"class":2707},[1903,5884,2711],{"class":2037},[1903,5886,5888,5891,5893],{"class":1905,"line":5887},100,[1903,5889,5890],{"class":2037},"      \u003C/",[1903,5892,2984],{"class":2707},[1903,5894,2711],{"class":2037},[1903,5896,5898,5901,5903],{"class":1905,"line":5897},101,[1903,5899,5900],{"class":2037},"    {:",[1903,5902,4412],{"class":2602},[1903,5904,2061],{"class":2037},[1903,5906,5908,5910,5912,5914,5916,5919],{"class":1905,"line":5907},102,[1903,5909,3009],{"class":2037},[1903,5911,2900],{"class":2707},[1903,5913,2903],{"class":1909},[1903,5915,2773],{"class":2602},[1903,5917,5918],{"class":1913},"\"profile-info\"",[1903,5920,2711],{"class":2037},[1903,5922,5924,5926,5928,5930,5932,5935],{"class":1905,"line":5923},103,[1903,5925,5601],{"class":2037},[1903,5927,2900],{"class":2707},[1903,5929,2903],{"class":1909},[1903,5931,2773],{"class":2602},[1903,5933,5934],{"class":1913},"\"profile-field\"",[1903,5936,2711],{"class":2037},[1903,5938,5940,5942,5944,5946,5948,5951,5953,5955],{"class":1905,"line":5939},104,[1903,5941,5530],{"class":2037},[1903,5943,1903],{"class":2707},[1903,5945,2903],{"class":1909},[1903,5947,2773],{"class":2602},[1903,5949,5950],{"class":1913},"\"field-label\"",[1903,5952,5544],{"class":2037},[1903,5954,1903],{"class":2707},[1903,5956,2711],{"class":2037},[1903,5958,5960,5962,5964,5966,5968,5970,5973,5975,5978,5981,5983],{"class":1905,"line":5959},105,[1903,5961,5530],{"class":2037},[1903,5963,1903],{"class":2707},[1903,5965,3616],{"class":1909},[1903,5967,2773],{"class":2602},[1903,5969,3621],{"class":1913},[1903,5971,5972],{"class":2037},">{userData?.firstName ",[1903,5974,3559],{"class":2602},[1903,5976,5977],{"class":1913}," \"Not set\"",[1903,5979,5980],{"class":2037},"}\u003C/",[1903,5982,1903],{"class":2707},[1903,5984,2711],{"class":2037},[1903,5986,5988,5990,5992],{"class":1905,"line":5987},106,[1903,5989,5586],{"class":2037},[1903,5991,2900],{"class":2707},[1903,5993,2711],{"class":2037},[1903,5995,5997,5999,6001,6003,6005,6007],{"class":1905,"line":5996},107,[1903,5998,5601],{"class":2037},[1903,6000,2900],{"class":2707},[1903,6002,2903],{"class":1909},[1903,6004,2773],{"class":2602},[1903,6006,5934],{"class":1913},[1903,6008,2711],{"class":2037},[1903,6010,6012,6014,6016,6018,6020,6022,6024,6026],{"class":1905,"line":6011},108,[1903,6013,5530],{"class":2037},[1903,6015,1903],{"class":2707},[1903,6017,2903],{"class":1909},[1903,6019,2773],{"class":2602},[1903,6021,5950],{"class":1913},[1903,6023,5628],{"class":2037},[1903,6025,1903],{"class":2707},[1903,6027,2711],{"class":2037},[1903,6029,6031,6033,6035,6037,6039,6041,6044,6046,6048,6050,6052],{"class":1905,"line":6030},109,[1903,6032,5530],{"class":2037},[1903,6034,1903],{"class":2707},[1903,6036,3616],{"class":1909},[1903,6038,2773],{"class":2602},[1903,6040,3621],{"class":1913},[1903,6042,6043],{"class":2037},">{userData.lastName ",[1903,6045,3559],{"class":2602},[1903,6047,5977],{"class":1913},[1903,6049,5980],{"class":2037},[1903,6051,1903],{"class":2707},[1903,6053,2711],{"class":2037},[1903,6055,6057,6059,6061],{"class":1905,"line":6056},110,[1903,6058,5586],{"class":2037},[1903,6060,2900],{"class":2707},[1903,6062,2711],{"class":2037},[1903,6064,6066,6068,6070,6072,6074,6076],{"class":1905,"line":6065},111,[1903,6067,5601],{"class":2037},[1903,6069,2900],{"class":2707},[1903,6071,2903],{"class":1909},[1903,6073,2773],{"class":2602},[1903,6075,5934],{"class":1913},[1903,6077,2711],{"class":2037},[1903,6079,6081,6083,6085,6087,6089,6091,6093,6095],{"class":1905,"line":6080},112,[1903,6082,5530],{"class":2037},[1903,6084,1903],{"class":2707},[1903,6086,2903],{"class":1909},[1903,6088,2773],{"class":2602},[1903,6090,5950],{"class":1913},[1903,6092,5707],{"class":2037},[1903,6094,1903],{"class":2707},[1903,6096,2711],{"class":2037},[1903,6098,6100,6102,6104,6106,6108,6110,6113,6115],{"class":1905,"line":6099},113,[1903,6101,5530],{"class":2037},[1903,6103,1903],{"class":2707},[1903,6105,3616],{"class":1909},[1903,6107,2773],{"class":2602},[1903,6109,3621],{"class":1913},[1903,6111,6112],{"class":2037},">{userData.email}\u003C/",[1903,6114,1903],{"class":2707},[1903,6116,2711],{"class":2037},[1903,6118,6120,6122,6124],{"class":1905,"line":6119},114,[1903,6121,5586],{"class":2037},[1903,6123,2900],{"class":2707},[1903,6125,2711],{"class":2037},[1903,6127,6129,6131,6133,6135,6137,6139,6141,6143,6145,6147,6149,6151,6154,6156,6159],{"class":1905,"line":6128},115,[1903,6130,5601],{"class":2037},[1903,6132,3227],{"class":2707},[1903,6134,2903],{"class":1909},[1903,6136,2773],{"class":2602},[1903,6138,5775],{"class":1913},[1903,6140,4926],{"class":1909},[1903,6142,2047],{"class":2037},[1903,6144,4931],{"class":1909},[1903,6146,2773],{"class":2602},[1903,6148,5827],{"class":2037},[1903,6150,4144],{"class":2602},[1903,6152,6153],{"class":2037}," (isEditing ",[1903,6155,2773],{"class":2602},[1903,6157,6158],{"class":2046}," true",[1903,6160,6161],{"class":2037},")}>\n",[1903,6163,6165],{"class":1905,"line":6164},116,[1903,6166,6167],{"class":2037},"          Edit Profile\n",[1903,6169,6171,6173,6175],{"class":1905,"line":6170},117,[1903,6172,5586],{"class":2037},[1903,6174,3227],{"class":2707},[1903,6176,2711],{"class":2037},[1903,6178,6180,6182,6184],{"class":1905,"line":6179},118,[1903,6181,5890],{"class":2037},[1903,6183,2900],{"class":2707},[1903,6185,2711],{"class":2037},[1903,6187,6189,6192,6195],{"class":1905,"line":6188},119,[1903,6190,6191],{"class":2037},"    {",[1903,6193,6194],{"class":2602},"/if",[1903,6196,2061],{"class":2037},[1903,6198,6200,6203,6205],{"class":1905,"line":6199},120,[1903,6201,6202],{"class":2037},"  {:",[1903,6204,4412],{"class":2602},[1903,6206,2061],{"class":2037},[1903,6208,6210,6212,6214,6216,6218,6221,6224,6226],{"class":1905,"line":6209},121,[1903,6211,2943],{"class":2037},[1903,6213,2900],{"class":2707},[1903,6215,2903],{"class":1909},[1903,6217,2773],{"class":2602},[1903,6219,6220],{"class":1913},"\"loading\"",[1903,6222,6223],{"class":2037},">Loading...\u003C/",[1903,6225,2900],{"class":2707},[1903,6227,2711],{"class":2037},[1903,6229,6231,6233,6235],{"class":1905,"line":6230},122,[1903,6232,2965],{"class":2037},[1903,6234,6194],{"class":2602},[1903,6236,2061],{"class":2037},[1903,6238,6240,6242,6244],{"class":1905,"line":6239},123,[1903,6241,2883],{"class":2602},[1903,6243,2900],{"class":2037},[1903,6245,2711],{"class":2602},[1844,6247,6248,6249,6252],{},"This displays a user profile page where users can view and update their profile details. Upon loading, it verifies authentication and fetches the user's profile data using Directus SDK's ",[1890,6250,6251],{},"readMe()"," function. If not authenticated, it redirects to the login page.",[1933,6254,6256],{"id":6255},"create-post-page","Create Post Page",[1844,6258,6259],{},"For the next step, you will create a page that fetches the posts from the Directus server and displays them inside this page, which will act as the page for displaying posts.",[1844,6261,4950,6262,2581,6264,4958,6266,6268],{},[1890,6263,1942],{},[1890,6265,4957],{},[1890,6267,2682],{}," file with the following contents:",[1895,6270,6272],{"className":2588,"code":6271,"language":2590,"meta":24,"style":24},"// src/routes/protected/posts/+page.svelte\n\n\u003Cscript>\n  import { readItems, deleteItem, readMe } from \"@directus/sdk\";\n  import { onMount } from \"svelte\";\n  import { client, isAuthenticated } from \"../../../lib/directus.js\";\n  import { goto } from \"$app/navigation\";\n\n  let posts = [];\n  let errorMessage = \"\";\n  let currentUserId = { id: null };\n\n  async function deletePost(id) {\n    if (confirm(\"Are you sure you want to delete this post?\")) {\n      try {\n        // Delete the post using Directus SDK\n        await client.request(deleteItem(\"posts\", id));\n        posts = posts.filter((post) => post.id !== id); // Remove the post from the list\n        errorMessage = \"\";\n      } catch (error) {\n        console.error(\"Error deleting post:\", error);\n        errorMessage = \"Failed to delete post. Please try again.\";\n      }\n    }\n  }\n\n  onMount(async () => {\n    console.log(\"onMount\");\n\n    // Check if the user is authenticated\n    const isAuth = await isAuthenticated();\n    console.log(\"isAuth\", isAuth);\n\n    if (isAuth.authenticated === false) {\n      goto(\"/login\"); // Redirect to login if not authenticated\n      return;\n    }\n\n    try {\n      // Fetch all posts using Directus SDK\n      const response = await client.request(readItems(\"posts\"));\n      posts = response;\n      console.log(\"posts\", posts);\n\n      // Fetch the current user ID\n      currentUserId = await client.request(readMe({ fields: [\"id\"] }));\n      console.log(\"Current user:\", currentUserId);\n\n      errorMessage = \"\";\n    } catch (error) {\n      console.error(\"Error fetching posts:\", error);\n      errorMessage = \"Failed to load posts. Please refresh the page.\";\n    }\n  });\n\u003C/script>\n\n\u003Ch1>My Posts\u003C/h1>\n\n{#if errorMessage}\n  \u003Cdiv class=\"error-message\">{errorMessage}\u003C/div>\n{/if}\n\n{#if posts.length > 0}\n  \u003Cdiv class=\"post-grid\">\n    {#each posts as post}\n      \u003Cdiv class=\"post-card\">\n        \u003Ch2>{post.title}\u003C/h2>\n        \u003Cp>{post.content.substring(0, 100)}...\u003C/p>\n\n        \u003Cdiv class=\"card-actions\">\n          {#if post.author === currentUserId?.id}\n            \u003Ca href=\"/protected/posts/{post.id}/edit\" class=\"button edit\">Edit\u003C/a>\n            \u003Cbutton class=\"button delete\" on:click={() => deletePost(post.id)}>Delete\u003C/button>\n          {/if}\n        \u003C/div>\n      \u003C/div>\n    {/each}\n  \u003C/div>\n{:else}\n  \u003Cp class=\"no-posts\">No posts found. Why not create one?\u003C/p>\n{/if}\n\n\u003Cdiv class=\"actions\">\n  \u003Ca href=\"/protected/posts/create\" class=\"button create\">Create New Post\u003C/a>\n  \u003Ca href=\"/protected\" class=\"button back\">Back to Dashboard\u003C/a>\n\u003C/div>\n",[1890,6273,6274,6279,6283,6291,6296,6300,6304,6308,6312,6317,6322,6331,6335,6340,6357,6362,6367,6389,6424,6436,6441,6459,6470,6474,6478,6482,6486,6490,6502,6506,6510,6522,6534,6538,6550,6564,6568,6572,6576,6580,6585,6609,6619,6628,6632,6637,6663,6673,6677,6688,6696,6705,6716,6720,6724,6732,6736,6749,6753,6764,6784,6793,6797,6816,6831,6844,6859,6872,6901,6905,6920,6930,6958,6993,7002,7010,7018,7027,7035,7044,7064,7072,7076,7091,7117,7143],{"__ignoreMap":24},[1903,6275,6276],{"class":1905,"line":1906},[1903,6277,6278],{"class":2178},"// src/routes/protected/posts/+page.svelte\n",[1903,6280,6281],{"class":1905,"line":1917},[1903,6282,2699],{"emptyLinePlaceholder":2698},[1903,6284,6285,6287,6289],{"class":1905,"line":1926},[1903,6286,2704],{"class":2037},[1903,6288,2708],{"class":2707},[1903,6290,2711],{"class":2037},[1903,6292,6293],{"class":1905,"line":2235},[1903,6294,6295],{"class":2037},"  import { readItems, deleteItem, readMe } from \"@directus/sdk\";\n",[1903,6297,6298],{"class":1905,"line":2247},[1903,6299,4994],{"class":2037},[1903,6301,6302],{"class":1905,"line":2252},[1903,6303,4984],{"class":2037},[1903,6305,6306],{"class":1905,"line":2272},[1903,6307,2726],{"class":2037},[1903,6309,6310],{"class":1905,"line":2280},[1903,6311,2699],{"emptyLinePlaceholder":2698},[1903,6313,6314],{"class":1905,"line":2285},[1903,6315,6316],{"class":2037},"  let posts = [];\n",[1903,6318,6319],{"class":1905,"line":2297},[1903,6320,6321],{"class":2037},"  let errorMessage = \"\";\n",[1903,6323,6324,6327,6329],{"class":1905,"line":2302},[1903,6325,6326],{"class":2037},"  let currentUserId = { id: ",[1903,6328,4232],{"class":2046},[1903,6330,4235],{"class":2037},[1903,6332,6333],{"class":1905,"line":2351},[1903,6334,2699],{"emptyLinePlaceholder":2698},[1903,6336,6337],{"class":1905,"line":2359},[1903,6338,6339],{"class":2037},"  async function deletePost(id) {\n",[1903,6341,6342,6344,6346,6349,6351,6354],{"class":1905,"line":2364},[1903,6343,4365],{"class":1909},[1903,6345,4315],{"class":2037},[1903,6347,6348],{"class":1909},"confirm",[1903,6350,2656],{"class":2037},[1903,6352,6353],{"class":1913},"\"Are you sure you want to delete this post?\"",[1903,6355,6356],{"class":2037},")) {\n",[1903,6358,6359],{"class":1905,"line":2396},[1903,6360,6361],{"class":2037},"      try {\n",[1903,6363,6364],{"class":1905,"line":2404},[1903,6365,6366],{"class":2178},"        // Delete the post using Directus SDK\n",[1903,6368,6369,6372,6374,6376,6378,6381,6383,6386],{"class":1905,"line":2409},[1903,6370,6371],{"class":2602},"        await",[1903,6373,2779],{"class":2037},[1903,6375,2782],{"class":1909},[1903,6377,2656],{"class":2037},[1903,6379,6380],{"class":1909},"deleteItem",[1903,6382,2656],{"class":2037},[1903,6384,6385],{"class":1913},"\"posts\"",[1903,6387,6388],{"class":2037},", id));\n",[1903,6390,6391,6394,6396,6399,6402,6405,6408,6410,6412,6415,6418,6421],{"class":1905,"line":2423},[1903,6392,6393],{"class":2037},"        posts ",[1903,6395,2773],{"class":2602},[1903,6397,6398],{"class":2037}," posts.",[1903,6400,6401],{"class":1909},"filter",[1903,6403,6404],{"class":2037},"((",[1903,6406,6407],{"class":4318},"post",[1903,6409,4338],{"class":2037},[1903,6411,4144],{"class":2602},[1903,6413,6414],{"class":2037}," post.id ",[1903,6416,6417],{"class":2602},"!==",[1903,6419,6420],{"class":2037}," id); ",[1903,6422,6423],{"class":2178},"// Remove the post from the list\n",[1903,6425,6426,6429,6431,6434],{"class":1905,"line":2428},[1903,6427,6428],{"class":2037},"        errorMessage ",[1903,6430,2773],{"class":2602},[1903,6432,6433],{"class":1913}," \"\"",[1903,6435,2615],{"class":2037},[1903,6437,6438],{"class":1905,"line":2444},[1903,6439,6440],{"class":2037},"      } catch (error) {\n",[1903,6442,6443,6446,6448,6450,6453,6455,6457],{"class":1905,"line":2452},[1903,6444,6445],{"class":2037},"        console.",[1903,6447,4209],{"class":1909},[1903,6449,2656],{"class":2037},[1903,6451,6452],{"class":1913},"\"Error deleting post:\"",[1903,6454,4327],{"class":2037},[1903,6456,4209],{"class":4318},[1903,6458,2837],{"class":2037},[1903,6460,6461,6463,6465,6468],{"class":1905,"line":2469},[1903,6462,6428],{"class":2037},[1903,6464,2773],{"class":2602},[1903,6466,6467],{"class":1913}," \"Failed to delete post. Please try again.\"",[1903,6469,2615],{"class":2037},[1903,6471,6472],{"class":1905,"line":2510},[1903,6473,3517],{"class":2037},[1903,6475,6476],{"class":1905,"line":2851},[1903,6477,2871],{"class":2037},[1903,6479,6480],{"class":1905,"line":2862},[1903,6481,2877],{"class":2037},[1903,6483,6484],{"class":1905,"line":2868},[1903,6485,2699],{"emptyLinePlaceholder":2698},[1903,6487,6488],{"class":1905,"line":2874},[1903,6489,5031],{"class":2037},[1903,6491,6492,6494,6496,6498,6500],{"class":1905,"line":2880},[1903,6493,4206],{"class":2037},[1903,6495,4491],{"class":1909},[1903,6497,2656],{"class":2037},[1903,6499,4642],{"class":1913},[1903,6501,2837],{"class":2037},[1903,6503,6504],{"class":1905,"line":2890},[1903,6505,2699],{"emptyLinePlaceholder":2698},[1903,6507,6508],{"class":1905,"line":2895},[1903,6509,5052],{"class":2178},[1903,6511,6512,6514,6516,6518,6520],{"class":1905,"line":2913},[1903,6513,5057],{"class":2037},[1903,6515,2773],{"class":2602},[1903,6517,2776],{"class":2602},[1903,6519,3458],{"class":1909},[1903,6521,3461],{"class":2037},[1903,6523,6524,6526,6528,6530,6532],{"class":1905,"line":2929},[1903,6525,4206],{"class":2037},[1903,6527,4491],{"class":1909},[1903,6529,2656],{"class":2037},[1903,6531,4668],{"class":1913},[1903,6533,4671],{"class":2037},[1903,6535,6536],{"class":1905,"line":2934},[1903,6537,2699],{"emptyLinePlaceholder":2698},[1903,6539,6540,6542,6544,6546,6548],{"class":1905,"line":2940},[1903,6541,4365],{"class":1909},[1903,6543,4683],{"class":2037},[1903,6545,4371],{"class":2602},[1903,6547,4688],{"class":2046},[1903,6549,4425],{"class":2037},[1903,6551,6552,6554,6556,6558,6561],{"class":1905,"line":2962},[1903,6553,2829],{"class":1909},[1903,6555,2656],{"class":2037},[1903,6557,2834],{"class":1913},[1903,6559,6560],{"class":2037},"); ",[1903,6562,6563],{"class":2178},"// Redirect to login if not authenticated\n",[1903,6565,6566],{"class":1905,"line":2974},[1903,6567,5108],{"class":2037},[1903,6569,6570],{"class":1905,"line":2979},[1903,6571,2871],{"class":2037},[1903,6573,6574],{"class":1905,"line":2991},[1903,6575,2699],{"emptyLinePlaceholder":2698},[1903,6577,6578],{"class":1905,"line":3006},[1903,6579,2765],{"class":2037},[1903,6581,6582],{"class":1905,"line":3015},[1903,6583,6584],{"class":2178},"      // Fetch all posts using Directus SDK\n",[1903,6586,6587,6589,6591,6593,6595,6597,6599,6602,6604,6606],{"class":1905,"line":3026},[1903,6588,2770],{"class":2037},[1903,6590,2773],{"class":2602},[1903,6592,2776],{"class":2602},[1903,6594,2779],{"class":2037},[1903,6596,2782],{"class":1909},[1903,6598,2656],{"class":2037},[1903,6600,6601],{"class":1909},"readItems",[1903,6603,2656],{"class":2037},[1903,6605,6385],{"class":1913},[1903,6607,6608],{"class":2037},"));\n",[1903,6610,6611,6614,6616],{"class":1905,"line":3042},[1903,6612,6613],{"class":2037},"      posts ",[1903,6615,2773],{"class":2602},[1903,6617,6618],{"class":2037}," response;\n",[1903,6620,6621,6623,6625],{"class":1905,"line":3053},[1903,6622,2818],{"class":2037},[1903,6624,6385],{"class":1913},[1903,6626,6627],{"class":2037},", posts);\n",[1903,6629,6630],{"class":1905,"line":3059},[1903,6631,2699],{"emptyLinePlaceholder":2698},[1903,6633,6634],{"class":1905,"line":3065},[1903,6635,6636],{"class":2178},"      // Fetch the current user ID\n",[1903,6638,6639,6642,6644,6646,6648,6650,6652,6654,6657,6660],{"class":1905,"line":3072},[1903,6640,6641],{"class":2037},"      currentUserId ",[1903,6643,2773],{"class":2602},[1903,6645,2776],{"class":2602},[1903,6647,2779],{"class":2037},[1903,6649,2782],{"class":1909},[1903,6651,2656],{"class":2037},[1903,6653,4175],{"class":1909},[1903,6655,6656],{"class":2037},"({ fields: [",[1903,6658,6659],{"class":1913},"\"id\"",[1903,6661,6662],{"class":2037},"] }));\n",[1903,6664,6665,6667,6670],{"class":1905,"line":3081},[1903,6666,2818],{"class":2037},[1903,6668,6669],{"class":1913},"\"Current user:\"",[1903,6671,6672],{"class":2037},", currentUserId);\n",[1903,6674,6675],{"class":1905,"line":3095},[1903,6676,2699],{"emptyLinePlaceholder":2698},[1903,6678,6679,6682,6684,6686],{"class":1905,"line":3105},[1903,6680,6681],{"class":2037},"      errorMessage ",[1903,6683,2773],{"class":2602},[1903,6685,6433],{"class":1913},[1903,6687,2615],{"class":2037},[1903,6689,6690,6692,6694],{"class":1905,"line":3110},[1903,6691,2842],{"class":2037},[1903,6693,2845],{"class":1909},[1903,6695,4201],{"class":2037},[1903,6697,6698,6700,6703],{"class":1905,"line":3115},[1903,6699,3573],{"class":2037},[1903,6701,6702],{"class":1913},"\"Error fetching posts:\"",[1903,6704,4217],{"class":2037},[1903,6706,6707,6709,6711,6714],{"class":1905,"line":3125},[1903,6708,6681],{"class":2037},[1903,6710,2773],{"class":2602},[1903,6712,6713],{"class":1913}," \"Failed to load posts. Please refresh the page.\"",[1903,6715,2615],{"class":2037},[1903,6717,6718],{"class":1905,"line":3166},[1903,6719,2871],{"class":2037},[1903,6721,6722],{"class":1905,"line":3173},[1903,6723,5248],{"class":2037},[1903,6725,6726,6728,6730],{"class":1905,"line":3184},[1903,6727,2883],{"class":2037},[1903,6729,2708],{"class":2707},[1903,6731,2711],{"class":2037},[1903,6733,6734],{"class":1905,"line":3199},[1903,6735,2699],{"emptyLinePlaceholder":2698},[1903,6737,6738,6740,6742,6745,6747],{"class":1905,"line":3210},[1903,6739,2704],{"class":2037},[1903,6741,2919],{"class":2707},[1903,6743,6744],{"class":2037},">My Posts\u003C/",[1903,6746,2919],{"class":2707},[1903,6748,2711],{"class":2037},[1903,6750,6751],{"class":1905,"line":3216},[1903,6752,2699],{"emptyLinePlaceholder":2698},[1903,6754,6755,6758,6761],{"class":1905,"line":3222},[1903,6756,6757],{"class":2037},"{#",[1903,6759,6760],{"class":2602},"if",[1903,6762,6763],{"class":2037}," errorMessage}\n",[1903,6765,6766,6768,6770,6772,6774,6777,6780,6782],{"class":1905,"line":3244},[1903,6767,2916],{"class":2037},[1903,6769,2900],{"class":2707},[1903,6771,2903],{"class":1909},[1903,6773,2773],{"class":2602},[1903,6775,6776],{"class":1913},"\"error-message\"",[1903,6778,6779],{"class":2037},">{errorMessage}\u003C/",[1903,6781,2900],{"class":2707},[1903,6783,2711],{"class":2037},[1903,6785,6786,6789,6791],{"class":1905,"line":3254},[1903,6787,6788],{"class":2037},"{",[1903,6790,6194],{"class":2602},[1903,6792,2061],{"class":2037},[1903,6794,6795],{"class":1905,"line":3270},[1903,6796,2699],{"emptyLinePlaceholder":2698},[1903,6798,6799,6801,6803,6805,6808,6811,6814],{"class":1905,"line":3292},[1903,6800,6757],{"class":2037},[1903,6802,6760],{"class":2602},[1903,6804,6398],{"class":2037},[1903,6806,6807],{"class":2046},"length",[1903,6809,6810],{"class":2602}," >",[1903,6812,6813],{"class":2046}," 0",[1903,6815,2061],{"class":2037},[1903,6817,6818,6820,6822,6824,6826,6829],{"class":1905,"line":3301},[1903,6819,2916],{"class":2037},[1903,6821,2900],{"class":2707},[1903,6823,2903],{"class":1909},[1903,6825,2773],{"class":2602},[1903,6827,6828],{"class":1913},"\"post-grid\"",[1903,6830,2711],{"class":2037},[1903,6832,6833,6836,6839,6842],{"class":1905,"line":3839},[1903,6834,6835],{"class":2037},"    {#each posts ",[1903,6837,6838],{"class":2602},"as",[1903,6840,6841],{"class":1909}," post",[1903,6843,2061],{"class":2037},[1903,6845,6846,6848,6850,6852,6854,6857],{"class":1905,"line":3844},[1903,6847,3009],{"class":2037},[1903,6849,2900],{"class":2707},[1903,6851,2903],{"class":1909},[1903,6853,2773],{"class":2602},[1903,6855,6856],{"class":1913},"\"post-card\"",[1903,6858,2711],{"class":2037},[1903,6860,6861,6863,6865,6868,6870],{"class":1905,"line":3859},[1903,6862,5601],{"class":2037},[1903,6864,1840],{"class":2707},[1903,6866,6867],{"class":2037},">{post.title}\u003C/",[1903,6869,1840],{"class":2707},[1903,6871,2711],{"class":2037},[1903,6873,6874,6876,6878,6881,6884,6886,6889,6891,6894,6897,6899],{"class":1905,"line":3881},[1903,6875,5601],{"class":2037},[1903,6877,1844],{"class":2707},[1903,6879,6880],{"class":2037},">{post.content.",[1903,6882,6883],{"class":1909},"substring",[1903,6885,2656],{"class":2037},[1903,6887,6888],{"class":2046},"0",[1903,6890,4327],{"class":2037},[1903,6892,6893],{"class":2046},"100",[1903,6895,6896],{"class":2037},")}...\u003C/",[1903,6898,1844],{"class":2707},[1903,6900,2711],{"class":2037},[1903,6902,6903],{"class":1905,"line":3890},[1903,6904,2699],{"emptyLinePlaceholder":2698},[1903,6906,6907,6909,6911,6913,6915,6918],{"class":1905,"line":5486},[1903,6908,5601],{"class":2037},[1903,6910,2900],{"class":2707},[1903,6912,2903],{"class":1909},[1903,6914,2773],{"class":2602},[1903,6916,6917],{"class":1913},"\"card-actions\"",[1903,6919,2711],{"class":2037},[1903,6921,6922,6925,6927],{"class":1905,"line":5491},[1903,6923,6924],{"class":2037},"          {#if post.author ",[1903,6926,4371],{"class":2602},[1903,6928,6929],{"class":2037}," currentUserId?.id}\n",[1903,6931,6932,6935,6937,6939,6941,6944,6946,6948,6951,6954,6956],{"class":1905,"line":5497},[1903,6933,6934],{"class":2037},"            \u003C",[1903,6936,1862],{"class":2707},[1903,6938,3278],{"class":1909},[1903,6940,2773],{"class":2602},[1903,6942,6943],{"class":1913},"\"/protected/posts/{post.id}/edit\"",[1903,6945,2903],{"class":1909},[1903,6947,2773],{"class":2602},[1903,6949,6950],{"class":1913},"\"button edit\"",[1903,6952,6953],{"class":2037},">Edit\u003C/",[1903,6955,1862],{"class":2707},[1903,6957,2711],{"class":2037},[1903,6959,6960,6962,6964,6966,6968,6971,6973,6975,6977,6979,6981,6983,6986,6989,6991],{"class":1905,"line":5503},[1903,6961,6934],{"class":2037},[1903,6963,3227],{"class":2707},[1903,6965,2903],{"class":1909},[1903,6967,2773],{"class":2602},[1903,6969,6970],{"class":1913},"\"button delete\"",[1903,6972,4926],{"class":1909},[1903,6974,2047],{"class":2037},[1903,6976,4931],{"class":1909},[1903,6978,2773],{"class":2602},[1903,6980,5827],{"class":2037},[1903,6982,4144],{"class":2602},[1903,6984,6985],{"class":1909}," deletePost",[1903,6987,6988],{"class":2037},"(post.id)}>Delete\u003C/",[1903,6990,3227],{"class":2707},[1903,6992,2711],{"class":2037},[1903,6994,6995,6998,7000],{"class":1905,"line":5513},[1903,6996,6997],{"class":2037},"          {",[1903,6999,2968],{"class":2602},[1903,7001,2971],{"class":2037},[1903,7003,7004,7006,7008],{"class":1905,"line":5527},[1903,7005,5586],{"class":2037},[1903,7007,2900],{"class":2707},[1903,7009,2711],{"class":2037},[1903,7011,7012,7014,7016],{"class":1905,"line":5551},[1903,7013,5890],{"class":2037},[1903,7015,2900],{"class":2707},[1903,7017,2711],{"class":2037},[1903,7019,7020,7022,7024],{"class":1905,"line":5583},[1903,7021,6191],{"class":2037},[1903,7023,2968],{"class":2602},[1903,7025,7026],{"class":2037},"each}\n",[1903,7028,7029,7031,7033],{"class":1905,"line":5593},[1903,7030,3247],{"class":2037},[1903,7032,2900],{"class":2707},[1903,7034,2711],{"class":2037},[1903,7036,7037,7040,7042],{"class":1905,"line":5598},[1903,7038,7039],{"class":2037},"{:",[1903,7041,4412],{"class":2602},[1903,7043,2061],{"class":2037},[1903,7045,7046,7048,7050,7052,7054,7057,7060,7062],{"class":1905,"line":5614},[1903,7047,2916],{"class":2037},[1903,7049,1844],{"class":2707},[1903,7051,2903],{"class":1909},[1903,7053,2773],{"class":2602},[1903,7055,7056],{"class":1913},"\"no-posts\"",[1903,7058,7059],{"class":2037},">No posts found. Why not create one?\u003C/",[1903,7061,1844],{"class":2707},[1903,7063,2711],{"class":2037},[1903,7065,7066,7068,7070],{"class":1905,"line":5635},[1903,7067,6788],{"class":2037},[1903,7069,6194],{"class":2602},[1903,7071,2061],{"class":2037},[1903,7073,7074],{"class":1905,"line":5665},[1903,7075,2699],{"emptyLinePlaceholder":2698},[1903,7077,7078,7080,7082,7084,7086,7089],{"class":1905,"line":5674},[1903,7079,2704],{"class":2037},[1903,7081,2900],{"class":2707},[1903,7083,2903],{"class":1909},[1903,7085,2773],{"class":2602},[1903,7087,7088],{"class":1913},"\"actions\"",[1903,7090,2711],{"class":2037},[1903,7092,7093,7095,7097,7099,7101,7103,7105,7107,7110,7113,7115],{"class":1905,"line":5679},[1903,7094,2916],{"class":2037},[1903,7096,1862],{"class":2707},[1903,7098,3278],{"class":1909},[1903,7100,2773],{"class":2602},[1903,7102,4866],{"class":1913},[1903,7104,2903],{"class":1909},[1903,7106,2773],{"class":2602},[1903,7108,7109],{"class":1913},"\"button create\"",[1903,7111,7112],{"class":2037},">Create New Post\u003C/",[1903,7114,1862],{"class":2707},[1903,7116,2711],{"class":2037},[1903,7118,7119,7121,7123,7125,7127,7129,7131,7133,7136,7139,7141],{"class":1905,"line":5694},[1903,7120,2916],{"class":2037},[1903,7122,1862],{"class":2707},[1903,7124,3278],{"class":1909},[1903,7126,2773],{"class":2602},[1903,7128,3493],{"class":1913},[1903,7130,2903],{"class":1909},[1903,7132,2773],{"class":2602},[1903,7134,7135],{"class":1913},"\"button back\"",[1903,7137,7138],{"class":2037},">Back to Dashboard\u003C/",[1903,7140,1862],{"class":2707},[1903,7142,2711],{"class":2037},[1903,7144,7145,7147,7149],{"class":1905,"line":5714},[1903,7146,2883],{"class":2037},[1903,7148,2900],{"class":2707},[1903,7150,2711],{"class":2037},[1844,7152,7153],{},"The code snippet above acts as the page where you can view and delete posts. It also includes a navigation where you can edit your post (which will be created soon).",[1844,7155,7156,7157,7160,7161,7164,7165,7168,7169,7172],{},"It retrieves a list of posts from the Directus backend using the ",[1890,7158,7159],{},"unMount"," function. This function utilizes the Directus SDK by calling ",[1890,7162,7163],{},"client.request(readItems('posts'))",". Also, a user can delete posts through the ",[1890,7166,7167],{},"deleteBlog(id)"," function which also uses the Directus SDK method to delete a specific blog by its ID from the 'posts' collection within Directus by calling ",[1890,7170,7171],{},"client.request(deleteItem('posts', id))",".\"",[1933,7174,7176],{"id":7175},"implement-the-create-and-edit-page","Implement the Create and Edit Page",[1844,7178,7179],{},"The post page should also allow users to create and edit posts.",[1844,7181,7182,7183,2581,7186,7189,7190,7192],{},"To implement the page to create a post, create a subdirectory called ",[1890,7184,7185],{},"create",[1890,7187,7188],{},"./src/routes/protected/posts"," directory. Create a ",[1890,7191,2682],{}," file inside it with the following code:",[1895,7194,7196],{"className":2588,"code":7195,"language":2590,"meta":24,"style":24},"// src/routes/protected/posts/create/+page.svelte\n\n\u003Cscript>\n  import { createItem } from \"@directus/sdk\";\n  import { goto } from \"$app/navigation\";\n  import { client, isAuthenticated } from \"../../../../lib/directus.js\";\n  import { onMount } from \"svelte\";\n\n  let title = \"\";\n  let content = \"\";\n  let userId;\n\n  onMount(async () => {\n    console.log(\"onMount\");\n\n    const isAuth = await isAuthenticated();\n    console.log(\"isAuth\", isAuth);\n\n    if (isAuth.authenticated === false) {\n      goto(\"/login\"); // Redirect to login if the user is not authenticated\n    } else {\n      userId = isAuth.user.id; // Get the logged-in user ID\n      console.log(\"userId\", userId);\n    }\n  });\n\n  async function handleSubmit() {\n    try {\n  \n      const response = await client.request(\n        createItem(\"posts\", {\n          title,\n          content,\n        })\n      );\n      console.log(\"response\", response);\n\n      // Redirect to the posts list after successful post creation\n      goto(\"/protected/posts\");\n    } catch (error) {\n      console.error(\"Error creating post:\", error);\n    }\n  }\n\u003C/script>\n\n\u003Ch1>Create New Post\u003C/h1>\n\n\u003Cform on:submit|preventDefault={handleSubmit}>\n  \u003Cdiv class=\"form-group\">\n    \u003Clabel for=\"title\">Title\u003C/label>\n    \u003Cinput id=\"title\" type=\"text\" bind:value={title} required />\n  \u003C/div>\n\n  \u003Cdiv class=\"form-group\">\n    \u003Clabel for=\"content\">Content\u003C/label>\n    \u003Ctextarea id=\"content\" bind:value={content} rows=\"10\" required>\u003C/textarea>\n  \u003C/div>\n\n  \u003Cbutton type=\"submit\" class=\"primary\">Create Post\u003C/button>\n\u003C/form>\n\n\u003Ca href=\"/protected/posts\" class=\"back-link\">Back to Posts\u003C/a>\n",[1890,7197,7198,7203,7207,7215,7220,7224,7229,7233,7237,7242,7247,7252,7256,7260,7272,7276,7288,7300,7304,7316,7329,7334,7347,7357,7361,7365,7369,7373,7377,7382,7396,7408,7413,7418,7422,7426,7435,7439,7444,7454,7462,7471,7475,7479,7487,7491,7503,7507,7515,7528,7547,7581,7589,7593,7607,7627,7668,7676,7680,7705,7713,7717],{"__ignoreMap":24},[1903,7199,7200],{"class":1905,"line":1906},[1903,7201,7202],{"class":2178},"// src/routes/protected/posts/create/+page.svelte\n",[1903,7204,7205],{"class":1905,"line":1917},[1903,7206,2699],{"emptyLinePlaceholder":2698},[1903,7208,7209,7211,7213],{"class":1905,"line":1926},[1903,7210,2704],{"class":2037},[1903,7212,2708],{"class":2707},[1903,7214,2711],{"class":2037},[1903,7216,7217],{"class":1905,"line":2235},[1903,7218,7219],{"class":2037},"  import { createItem } from \"@directus/sdk\";\n",[1903,7221,7222],{"class":1905,"line":2247},[1903,7223,2726],{"class":2037},[1903,7225,7226],{"class":1905,"line":2252},[1903,7227,7228],{"class":2037},"  import { client, isAuthenticated } from \"../../../../lib/directus.js\";\n",[1903,7230,7231],{"class":1905,"line":2272},[1903,7232,4994],{"class":2037},[1903,7234,7235],{"class":1905,"line":2280},[1903,7236,2699],{"emptyLinePlaceholder":2698},[1903,7238,7239],{"class":1905,"line":2285},[1903,7240,7241],{"class":2037},"  let title = \"\";\n",[1903,7243,7244],{"class":1905,"line":2297},[1903,7245,7246],{"class":2037},"  let content = \"\";\n",[1903,7248,7249],{"class":1905,"line":2302},[1903,7250,7251],{"class":2037},"  let userId;\n",[1903,7253,7254],{"class":1905,"line":2351},[1903,7255,2699],{"emptyLinePlaceholder":2698},[1903,7257,7258],{"class":1905,"line":2359},[1903,7259,5031],{"class":2037},[1903,7261,7262,7264,7266,7268,7270],{"class":1905,"line":2364},[1903,7263,4206],{"class":2037},[1903,7265,4491],{"class":1909},[1903,7267,2656],{"class":2037},[1903,7269,4642],{"class":1913},[1903,7271,2837],{"class":2037},[1903,7273,7274],{"class":1905,"line":2396},[1903,7275,2699],{"emptyLinePlaceholder":2698},[1903,7277,7278,7280,7282,7284,7286],{"class":1905,"line":2404},[1903,7279,5057],{"class":2037},[1903,7281,2773],{"class":2602},[1903,7283,2776],{"class":2602},[1903,7285,3458],{"class":1909},[1903,7287,3461],{"class":2037},[1903,7289,7290,7292,7294,7296,7298],{"class":1905,"line":2409},[1903,7291,4206],{"class":2037},[1903,7293,4491],{"class":1909},[1903,7295,2656],{"class":2037},[1903,7297,4668],{"class":1913},[1903,7299,4671],{"class":2037},[1903,7301,7302],{"class":1905,"line":2423},[1903,7303,2699],{"emptyLinePlaceholder":2698},[1903,7305,7306,7308,7310,7312,7314],{"class":1905,"line":2428},[1903,7307,4365],{"class":1909},[1903,7309,4683],{"class":2037},[1903,7311,4371],{"class":2602},[1903,7313,4688],{"class":2046},[1903,7315,4425],{"class":2037},[1903,7317,7318,7320,7322,7324,7326],{"class":1905,"line":2444},[1903,7319,2829],{"class":1909},[1903,7321,2656],{"class":2037},[1903,7323,2834],{"class":1913},[1903,7325,6560],{"class":2037},[1903,7327,7328],{"class":2178},"// Redirect to login if the user is not authenticated\n",[1903,7330,7331],{"class":1905,"line":2452},[1903,7332,7333],{"class":2037},"    } else {\n",[1903,7335,7336,7339,7341,7344],{"class":1905,"line":2469},[1903,7337,7338],{"class":2037},"      userId ",[1903,7340,2773],{"class":2602},[1903,7342,7343],{"class":2037}," isAuth.user.id; ",[1903,7345,7346],{"class":2178},"// Get the logged-in user ID\n",[1903,7348,7349,7351,7354],{"class":1905,"line":2510},[1903,7350,2818],{"class":2037},[1903,7352,7353],{"class":1913},"\"userId\"",[1903,7355,7356],{"class":2037},", userId);\n",[1903,7358,7359],{"class":1905,"line":2851},[1903,7360,2871],{"class":2037},[1903,7362,7363],{"class":1905,"line":2862},[1903,7364,5248],{"class":2037},[1903,7366,7367],{"class":1905,"line":2868},[1903,7368,2699],{"emptyLinePlaceholder":2698},[1903,7370,7371],{"class":1905,"line":2874},[1903,7372,5257],{"class":2037},[1903,7374,7375],{"class":1905,"line":2880},[1903,7376,2765],{"class":2037},[1903,7378,7379],{"class":1905,"line":2890},[1903,7380,7381],{"class":2037},"  \n",[1903,7383,7384,7386,7388,7390,7392,7394],{"class":1905,"line":2895},[1903,7385,2770],{"class":2037},[1903,7387,2773],{"class":2602},[1903,7389,2776],{"class":2602},[1903,7391,2779],{"class":2037},[1903,7393,2782],{"class":1909},[1903,7395,2785],{"class":2037},[1903,7397,7398,7401,7403,7405],{"class":1905,"line":2913},[1903,7399,7400],{"class":1909},"        createItem",[1903,7402,2656],{"class":2037},[1903,7404,6385],{"class":1913},[1903,7406,7407],{"class":2037},", {\n",[1903,7409,7410],{"class":1905,"line":2929},[1903,7411,7412],{"class":2037},"          title,\n",[1903,7414,7415],{"class":1905,"line":2934},[1903,7416,7417],{"class":2037},"          content,\n",[1903,7419,7420],{"class":1905,"line":2940},[1903,7421,2808],{"class":2037},[1903,7423,7424],{"class":1905,"line":2962},[1903,7425,2813],{"class":2037},[1903,7427,7428,7430,7433],{"class":1905,"line":2974},[1903,7429,2818],{"class":2037},[1903,7431,7432],{"class":1913},"\"response\"",[1903,7434,2824],{"class":2037},[1903,7436,7437],{"class":1905,"line":2979},[1903,7438,2699],{"emptyLinePlaceholder":2698},[1903,7440,7441],{"class":1905,"line":2991},[1903,7442,7443],{"class":2178},"      // Redirect to the posts list after successful post creation\n",[1903,7445,7446,7448,7450,7452],{"class":1905,"line":3006},[1903,7447,2829],{"class":1909},[1903,7449,2656],{"class":2037},[1903,7451,4839],{"class":1913},[1903,7453,2837],{"class":2037},[1903,7455,7456,7458,7460],{"class":1905,"line":3015},[1903,7457,2842],{"class":2037},[1903,7459,2845],{"class":1909},[1903,7461,4201],{"class":2037},[1903,7463,7464,7466,7469],{"class":1905,"line":3026},[1903,7465,3573],{"class":2037},[1903,7467,7468],{"class":1913},"\"Error creating post:\"",[1903,7470,4217],{"class":2037},[1903,7472,7473],{"class":1905,"line":3042},[1903,7474,2871],{"class":2037},[1903,7476,7477],{"class":1905,"line":3053},[1903,7478,2877],{"class":2037},[1903,7480,7481,7483,7485],{"class":1905,"line":3059},[1903,7482,2883],{"class":2037},[1903,7484,2708],{"class":2707},[1903,7486,2711],{"class":2037},[1903,7488,7489],{"class":1905,"line":3065},[1903,7490,2699],{"emptyLinePlaceholder":2698},[1903,7492,7493,7495,7497,7499,7501],{"class":1905,"line":3072},[1903,7494,2704],{"class":2037},[1903,7496,2919],{"class":2707},[1903,7498,7112],{"class":2037},[1903,7500,2919],{"class":2707},[1903,7502,2711],{"class":2037},[1903,7504,7505],{"class":1905,"line":3081},[1903,7506,2699],{"emptyLinePlaceholder":2698},[1903,7508,7509,7511,7513],{"class":1905,"line":3095},[1903,7510,2704],{"class":2037},[1903,7512,2984],{"class":2707},[1903,7514,5510],{"class":2987},[1903,7516,7517,7520,7522,7524,7526],{"class":1905,"line":3105},[1903,7518,7519],{"class":2987},"  \u003Cdiv",[1903,7521,2903],{"class":1909},[1903,7523,2773],{"class":2602},[1903,7525,3001],{"class":1913},[1903,7527,2711],{"class":2037},[1903,7529,7530,7532,7534,7536,7538,7540,7543,7545],{"class":1905,"line":3110},[1903,7531,2943],{"class":2037},[1903,7533,5533],{"class":2707},[1903,7535,5536],{"class":1909},[1903,7537,2773],{"class":2602},[1903,7539,5440],{"class":1913},[1903,7541,7542],{"class":2037},">Title\u003C/",[1903,7544,5533],{"class":2707},[1903,7546,2711],{"class":2037},[1903,7548,7549,7551,7553,7555,7557,7559,7561,7563,7565,7567,7569,7571,7573,7576,7579],{"class":1905,"line":3115},[1903,7550,2943],{"class":2037},[1903,7552,3130],{"class":2707},[1903,7554,5565],{"class":1909},[1903,7556,2773],{"class":2602},[1903,7558,5440],{"class":1913},[1903,7560,2260],{"class":1909},[1903,7562,2773],{"class":2602},[1903,7564,5562],{"class":1913},[1903,7566,3140],{"class":1909},[1903,7568,2047],{"class":2037},[1903,7570,3034],{"class":1909},[1903,7572,2773],{"class":2602},[1903,7574,7575],{"class":2037},"{title} ",[1903,7577,7578],{"class":1909},"required",[1903,7580,3163],{"class":2037},[1903,7582,7583,7585,7587],{"class":1905,"line":3125},[1903,7584,3247],{"class":2037},[1903,7586,2900],{"class":2707},[1903,7588,2711],{"class":2037},[1903,7590,7591],{"class":1905,"line":3166},[1903,7592,2699],{"emptyLinePlaceholder":2698},[1903,7594,7595,7597,7599,7601,7603,7605],{"class":1905,"line":3173},[1903,7596,2916],{"class":2037},[1903,7598,2900],{"class":2707},[1903,7600,2903],{"class":1909},[1903,7602,2773],{"class":2602},[1903,7604,3001],{"class":1913},[1903,7606,2711],{"class":2037},[1903,7608,7609,7611,7613,7615,7617,7620,7623,7625],{"class":1905,"line":3184},[1903,7610,2943],{"class":2037},[1903,7612,5533],{"class":2707},[1903,7614,5536],{"class":1909},[1903,7616,2773],{"class":2602},[1903,7618,7619],{"class":1913},"\"content\"",[1903,7621,7622],{"class":2037},">Content\u003C/",[1903,7624,5533],{"class":2707},[1903,7626,2711],{"class":2037},[1903,7628,7629,7631,7634,7636,7638,7640,7642,7644,7646,7648,7651,7654,7656,7659,7661,7664,7666],{"class":1905,"line":3199},[1903,7630,2943],{"class":2037},[1903,7632,7633],{"class":2707},"textarea",[1903,7635,5565],{"class":1909},[1903,7637,2773],{"class":2602},[1903,7639,7619],{"class":1913},[1903,7641,3140],{"class":1909},[1903,7643,2047],{"class":2037},[1903,7645,3034],{"class":1909},[1903,7647,2773],{"class":2602},[1903,7649,7650],{"class":2037},"{content} ",[1903,7652,7653],{"class":1909},"rows",[1903,7655,2773],{"class":2602},[1903,7657,7658],{"class":1913},"\"10\"",[1903,7660,3160],{"class":1909},[1903,7662,7663],{"class":2037},">\u003C/",[1903,7665,7633],{"class":2707},[1903,7667,2711],{"class":2037},[1903,7669,7670,7672,7674],{"class":1905,"line":3210},[1903,7671,3247],{"class":2037},[1903,7673,2900],{"class":2707},[1903,7675,2711],{"class":2037},[1903,7677,7678],{"class":1905,"line":3216},[1903,7679,2699],{"emptyLinePlaceholder":2698},[1903,7681,7682,7684,7686,7688,7690,7692,7694,7696,7698,7701,7703],{"class":1905,"line":3222},[1903,7683,2916],{"class":2037},[1903,7685,3227],{"class":2707},[1903,7687,2260],{"class":1909},[1903,7689,2773],{"class":2602},[1903,7691,3234],{"class":1913},[1903,7693,2903],{"class":1909},[1903,7695,2773],{"class":2602},[1903,7697,5775],{"class":1913},[1903,7699,7700],{"class":2037},">Create Post\u003C/",[1903,7702,3227],{"class":2707},[1903,7704,2711],{"class":2037},[1903,7706,7707,7709,7711],{"class":1905,"line":3244},[1903,7708,2883],{"class":2602},[1903,7710,2984],{"class":2037},[1903,7712,2711],{"class":2602},[1903,7714,7715],{"class":1905,"line":3254},[1903,7716,2699],{"emptyLinePlaceholder":2698},[1903,7718,7719,7721,7723,7725,7727,7729,7731,7733,7736,7739,7741],{"class":1905,"line":3270},[1903,7720,2704],{"class":2037},[1903,7722,1862],{"class":2707},[1903,7724,3278],{"class":1909},[1903,7726,2773],{"class":2602},[1903,7728,4839],{"class":1913},[1903,7730,2903],{"class":1909},[1903,7732,2773],{"class":2602},[1903,7734,7735],{"class":1913},"\"back-link\"",[1903,7737,7738],{"class":2037},">Back to Posts\u003C/",[1903,7740,1862],{"class":2707},[1903,7742,2711],{"class":2037},[1844,7744,7745,7746,1885],{},"The code above is used to create a new post. It captures the user input for the post title and content and sends the data to the backend using ",[1890,7747,7748],{},"createItem",[1844,7750,7751,7752,2581,7755,7757,7758,7761,7762,3329],{},"To edit a post, create a subdirectory called ",[1890,7753,7754],{},"[id]",[1890,7756,7188],{}," directory. Inside it, create another subdirectory called ",[1890,7759,7760],{},"edit",", and afterward, create a ",[1890,7763,2682],{},[1895,7765,7767],{"className":2588,"code":7766,"language":2590,"meta":24,"style":24},"//  src/routes/protected/posts/[id]/edit/+page.svelte\n\u003Cscript>\n  import { readItem, updateItem } from \"@directus/sdk\";\n  import { client, isAuthenticated } from \"../../../../../lib/directus.js\";\n  import { goto } from \"$app/navigation\";\n  import { page } from \"$app/stores\";\n  import { onMount } from \"svelte\";\n\n  const postId = $page.params.id; \n  let isLoading = true;\n  let message = \"\";\n\n  let post = {\n    title: \"\",\n    content: \"\",\n  };\n\n  onMount(async () => {\n    const isAuth = await isAuthenticated();\n    console.log(\"isAuth\", isAuth);\n\n    if (isAuth.authenticated === false) {\n      goto(\"/login\"); \n      return;\n    }\n\n    await loadPost();\n  });\n\n  async function loadPost() {\n    isLoading = true; \n    try {\n      const response = await client.request(readItem(\"posts\", postId));\n      if (\n        response &&\n        typeof response.title === \"string\" &&\n        typeof response.content === \"string\"\n      ) {\n        post = { title: response.title, content: response.content };\n      }\n    } catch (error) {\n      console.error(\"Error fetching post:\", error);\n      message = \"Failed to load post details. Please try again.\";\n    }\n    isLoading = false;\n  }\n\n  async function handleSubmit() {\n    isLoading = true; \n    try {\n      // Update the post using the Directus SDK\n      await client.request(\n        updateItem(\"posts\", postId, {\n          title: post.title,\n          content: post.content,\n        })\n      );\n      goto(\"/protected/posts\"); \n    } catch (error) {\n      console.error(\"Error updating post:\", error);\n      message = \"Failed to update post. Please try again.\";\n    }\n    isLoading = false;\n  }\n\u003C/script>\n\n\u003Cdiv class=\"edit-container\">\n  \u003Ch1>Edit Post\u003C/h1>\n\n  {#if isLoading}\n    \u003Cp class=\"loading\">Loading Post details...\u003C/p>\n  {:else}\n    {#if message}\n      \u003Cp class=\"error\">{message}\u003C/p>\n    {/if}\n\n    \u003Cform on:submit|preventDefault={handleSubmit}>\n      \u003Cdiv class=\"form-group\">\n        \u003Clabel for=\"title\">Title\u003C/label>\n        \u003Cinput type=\"text\" id=\"title\" bind:value={post.title} required />\n      \u003C/div>\n\n      \u003Cdiv class=\"form-group\">\n        \u003Clabel for=\"content\">Content\u003C/label>\n        \u003Ctextarea id=\"content\" bind:value={post.content} rows=\"10\" required>\u003C/textarea>\n      \u003C/div>\n\n      \u003Cdiv class=\"actions\">\n        \u003Cbutton type=\"submit\" class=\"button save\">Save Changes\u003C/button>\n        \u003Ca href=\"/protected/posts\" class=\"button cancel\">Cancel\u003C/a>\n      \u003C/div>\n    \u003C/form>\n  {/if}\n\u003C/div>\n",[1890,7768,7769,7774,7782,7787,7792,7796,7801,7805,7809,7814,7819,7823,7827,7832,7843,7852,7857,7861,7865,7877,7889,7893,7905,7915,7919,7923,7927,7937,7941,7945,7950,7962,7966,7990,7997,8005,8018,8028,8033,8043,8047,8055,8064,8075,8079,8089,8093,8097,8101,8111,8115,8120,8125,8141,8157,8172,8176,8180,8190,8198,8207,8218,8222,8232,8236,8244,8248,8263,8276,8280,8285,8304,8309,8314,8332,8340,8344,8352,8365,8383,8416,8424,8428,8442,8460,8497,8505,8509,8523,8549,8575,8583,8591,8599],{"__ignoreMap":24},[1903,7770,7771],{"class":1905,"line":1906},[1903,7772,7773],{"class":2178},"//  src/routes/protected/posts/[id]/edit/+page.svelte\n",[1903,7775,7776,7778,7780],{"class":1905,"line":1917},[1903,7777,2704],{"class":2037},[1903,7779,2708],{"class":2707},[1903,7781,2711],{"class":2037},[1903,7783,7784],{"class":1905,"line":1926},[1903,7785,7786],{"class":2037},"  import { readItem, updateItem } from \"@directus/sdk\";\n",[1903,7788,7789],{"class":1905,"line":2235},[1903,7790,7791],{"class":2037},"  import { client, isAuthenticated } from \"../../../../../lib/directus.js\";\n",[1903,7793,7794],{"class":1905,"line":2247},[1903,7795,2726],{"class":2037},[1903,7797,7798],{"class":1905,"line":2252},[1903,7799,7800],{"class":2037},"  import { page } from \"$app/stores\";\n",[1903,7802,7803],{"class":1905,"line":2272},[1903,7804,4994],{"class":2037},[1903,7806,7807],{"class":1905,"line":2280},[1903,7808,2699],{"emptyLinePlaceholder":2698},[1903,7810,7811],{"class":1905,"line":2285},[1903,7812,7813],{"class":2037},"  const postId = $page.params.id; \n",[1903,7815,7816],{"class":1905,"line":2297},[1903,7817,7818],{"class":2037},"  let isLoading = true;\n",[1903,7820,7821],{"class":1905,"line":2302},[1903,7822,5022],{"class":2037},[1903,7824,7825],{"class":1905,"line":2351},[1903,7826,2699],{"emptyLinePlaceholder":2698},[1903,7828,7829],{"class":1905,"line":2359},[1903,7830,7831],{"class":2037},"  let post = {\n",[1903,7833,7834,7837,7840],{"class":1905,"line":2364},[1903,7835,7836],{"class":2037},"    title: ",[1903,7838,7839],{"class":1913},"\"\"",[1903,7841,7842],{"class":2037},",\n",[1903,7844,7845,7848,7850],{"class":1905,"line":2396},[1903,7846,7847],{"class":2037},"    content: ",[1903,7849,7839],{"class":1913},[1903,7851,7842],{"class":2037},[1903,7853,7854],{"class":1905,"line":2404},[1903,7855,7856],{"class":2037},"  };\n",[1903,7858,7859],{"class":1905,"line":2409},[1903,7860,2699],{"emptyLinePlaceholder":2698},[1903,7862,7863],{"class":1905,"line":2423},[1903,7864,5031],{"class":2037},[1903,7866,7867,7869,7871,7873,7875],{"class":1905,"line":2428},[1903,7868,5057],{"class":2037},[1903,7870,2773],{"class":2602},[1903,7872,2776],{"class":2602},[1903,7874,3458],{"class":1909},[1903,7876,3461],{"class":2037},[1903,7878,7879,7881,7883,7885,7887],{"class":1905,"line":2444},[1903,7880,4206],{"class":2037},[1903,7882,4491],{"class":1909},[1903,7884,2656],{"class":2037},[1903,7886,4668],{"class":1913},[1903,7888,4671],{"class":2037},[1903,7890,7891],{"class":1905,"line":2452},[1903,7892,2699],{"emptyLinePlaceholder":2698},[1903,7894,7895,7897,7899,7901,7903],{"class":1905,"line":2469},[1903,7896,4365],{"class":1909},[1903,7898,4683],{"class":2037},[1903,7900,4371],{"class":2602},[1903,7902,4688],{"class":2046},[1903,7904,4425],{"class":2037},[1903,7906,7907,7909,7911,7913],{"class":1905,"line":2510},[1903,7908,2829],{"class":1909},[1903,7910,2656],{"class":2037},[1903,7912,2834],{"class":1913},[1903,7914,4747],{"class":2037},[1903,7916,7917],{"class":1905,"line":2851},[1903,7918,5108],{"class":2037},[1903,7920,7921],{"class":1905,"line":2862},[1903,7922,2871],{"class":2037},[1903,7924,7925],{"class":1905,"line":2868},[1903,7926,2699],{"emptyLinePlaceholder":2698},[1903,7928,7929,7932,7935],{"class":1905,"line":2874},[1903,7930,7931],{"class":2602},"    await",[1903,7933,7934],{"class":1909}," loadPost",[1903,7936,3461],{"class":2037},[1903,7938,7939],{"class":1905,"line":2880},[1903,7940,5248],{"class":2037},[1903,7942,7943],{"class":1905,"line":2890},[1903,7944,2699],{"emptyLinePlaceholder":2698},[1903,7946,7947],{"class":1905,"line":2895},[1903,7948,7949],{"class":2037},"  async function loadPost() {\n",[1903,7951,7952,7955,7957,7959],{"class":1905,"line":2913},[1903,7953,7954],{"class":2037},"    isLoading ",[1903,7956,2773],{"class":2602},[1903,7958,6158],{"class":2046},[1903,7960,7961],{"class":2037},"; \n",[1903,7963,7964],{"class":1905,"line":2929},[1903,7965,2765],{"class":2037},[1903,7967,7968,7970,7972,7974,7976,7978,7980,7983,7985,7987],{"class":1905,"line":2934},[1903,7969,2770],{"class":2037},[1903,7971,2773],{"class":2602},[1903,7973,2776],{"class":2602},[1903,7975,2779],{"class":2037},[1903,7977,2782],{"class":1909},[1903,7979,2656],{"class":2037},[1903,7981,7982],{"class":1909},"readItem",[1903,7984,2656],{"class":2037},[1903,7986,6385],{"class":1913},[1903,7988,7989],{"class":2037},", postId));\n",[1903,7991,7992,7994],{"class":1905,"line":2940},[1903,7993,3480],{"class":1909},[1903,7995,7996],{"class":2037}," (\n",[1903,7998,7999,8002],{"class":1905,"line":2962},[1903,8000,8001],{"class":4318},"        response",[1903,8003,8004],{"class":2037}," &&\n",[1903,8006,8007,8010,8013,8016],{"class":1905,"line":2974},[1903,8008,8009],{"class":4318},"        typeof",[1903,8011,8012],{"class":2037}," response.title === ",[1903,8014,8015],{"class":1913},"\"string\"",[1903,8017,8004],{"class":2037},[1903,8019,8020,8022,8025],{"class":1905,"line":2979},[1903,8021,8009],{"class":4318},[1903,8023,8024],{"class":2037}," response.content === ",[1903,8026,8027],{"class":1913},"\"string\"\n",[1903,8029,8030],{"class":1905,"line":2991},[1903,8031,8032],{"class":2037},"      ) {\n",[1903,8034,8035,8038,8040],{"class":1905,"line":3006},[1903,8036,8037],{"class":2037},"        post ",[1903,8039,2773],{"class":2602},[1903,8041,8042],{"class":2037}," { title: response.title, content: response.content };\n",[1903,8044,8045],{"class":1905,"line":3015},[1903,8046,3517],{"class":2037},[1903,8048,8049,8051,8053],{"class":1905,"line":3026},[1903,8050,2842],{"class":2037},[1903,8052,2845],{"class":1909},[1903,8054,4201],{"class":2037},[1903,8056,8057,8059,8062],{"class":1905,"line":3042},[1903,8058,3573],{"class":2037},[1903,8060,8061],{"class":1913},"\"Error fetching post:\"",[1903,8063,4217],{"class":2037},[1903,8065,8066,8068,8070,8073],{"class":1905,"line":3053},[1903,8067,5334],{"class":2037},[1903,8069,2773],{"class":2602},[1903,8071,8072],{"class":1913}," \"Failed to load post details. Please try again.\"",[1903,8074,2615],{"class":2037},[1903,8076,8077],{"class":1905,"line":3059},[1903,8078,2871],{"class":2037},[1903,8080,8081,8083,8085,8087],{"class":1905,"line":3065},[1903,8082,7954],{"class":2037},[1903,8084,2773],{"class":2602},[1903,8086,4688],{"class":2046},[1903,8088,2615],{"class":2037},[1903,8090,8091],{"class":1905,"line":3072},[1903,8092,2877],{"class":2037},[1903,8094,8095],{"class":1905,"line":3081},[1903,8096,2699],{"emptyLinePlaceholder":2698},[1903,8098,8099],{"class":1905,"line":3095},[1903,8100,5257],{"class":2037},[1903,8102,8103,8105,8107,8109],{"class":1905,"line":3105},[1903,8104,7954],{"class":2037},[1903,8106,2773],{"class":2602},[1903,8108,6158],{"class":2046},[1903,8110,7961],{"class":2037},[1903,8112,8113],{"class":1905,"line":3110},[1903,8114,2765],{"class":2037},[1903,8116,8117],{"class":1905,"line":3115},[1903,8118,8119],{"class":2178},"      // Update the post using the Directus SDK\n",[1903,8121,8122],{"class":1905,"line":3125},[1903,8123,8124],{"class":2037},"      await client.request(\n",[1903,8126,8127,8130,8132,8134,8136,8139],{"class":1905,"line":3166},[1903,8128,8129],{"class":1909},"        updateItem",[1903,8131,2656],{"class":2037},[1903,8133,6385],{"class":1913},[1903,8135,4327],{"class":2037},[1903,8137,8138],{"class":4318},"postId",[1903,8140,7407],{"class":2037},[1903,8142,8143,8146,8149,8151,8153,8155],{"class":1905,"line":3173},[1903,8144,8145],{"class":4318},"          title",[1903,8147,8148],{"class":2037},": ",[1903,8150,6407],{"class":4318},[1903,8152,1885],{"class":2037},[1903,8154,1954],{"class":4318},[1903,8156,7842],{"class":2037},[1903,8158,8159,8162,8164,8166,8168,8170],{"class":1905,"line":3184},[1903,8160,8161],{"class":4318},"          content",[1903,8163,8148],{"class":2037},[1903,8165,6407],{"class":4318},[1903,8167,1885],{"class":2037},[1903,8169,1960],{"class":4318},[1903,8171,7842],{"class":2037},[1903,8173,8174],{"class":1905,"line":3199},[1903,8175,2808],{"class":2037},[1903,8177,8178],{"class":1905,"line":3210},[1903,8179,2813],{"class":2037},[1903,8181,8182,8184,8186,8188],{"class":1905,"line":3216},[1903,8183,2829],{"class":1909},[1903,8185,2656],{"class":2037},[1903,8187,4839],{"class":1913},[1903,8189,4747],{"class":2037},[1903,8191,8192,8194,8196],{"class":1905,"line":3222},[1903,8193,2842],{"class":2037},[1903,8195,2845],{"class":1909},[1903,8197,4201],{"class":2037},[1903,8199,8200,8202,8205],{"class":1905,"line":3244},[1903,8201,3573],{"class":2037},[1903,8203,8204],{"class":1913},"\"Error updating post:\"",[1903,8206,4217],{"class":2037},[1903,8208,8209,8211,8213,8216],{"class":1905,"line":3254},[1903,8210,5334],{"class":2037},[1903,8212,2773],{"class":2602},[1903,8214,8215],{"class":1913}," \"Failed to update post. Please try again.\"",[1903,8217,2615],{"class":2037},[1903,8219,8220],{"class":1905,"line":3270},[1903,8221,2871],{"class":2037},[1903,8223,8224,8226,8228,8230],{"class":1905,"line":3292},[1903,8225,7954],{"class":2037},[1903,8227,2773],{"class":2602},[1903,8229,4688],{"class":2046},[1903,8231,2615],{"class":2037},[1903,8233,8234],{"class":1905,"line":3301},[1903,8235,2877],{"class":2037},[1903,8237,8238,8240,8242],{"class":1905,"line":3839},[1903,8239,2883],{"class":2037},[1903,8241,2708],{"class":2707},[1903,8243,2711],{"class":2037},[1903,8245,8246],{"class":1905,"line":3844},[1903,8247,2699],{"emptyLinePlaceholder":2698},[1903,8249,8250,8252,8254,8256,8258,8261],{"class":1905,"line":3859},[1903,8251,2704],{"class":2037},[1903,8253,2900],{"class":2707},[1903,8255,2903],{"class":1909},[1903,8257,2773],{"class":2602},[1903,8259,8260],{"class":1913},"\"edit-container\"",[1903,8262,2711],{"class":2037},[1903,8264,8265,8267,8269,8272,8274],{"class":1905,"line":3881},[1903,8266,2916],{"class":2037},[1903,8268,2919],{"class":2707},[1903,8270,8271],{"class":2037},">Edit Post\u003C/",[1903,8273,2919],{"class":2707},[1903,8275,2711],{"class":2037},[1903,8277,8278],{"class":1905,"line":3890},[1903,8279,2699],{"emptyLinePlaceholder":2698},[1903,8281,8282],{"class":1905,"line":5486},[1903,8283,8284],{"class":2037},"  {#if isLoading}\n",[1903,8286,8287,8289,8291,8293,8295,8297,8300,8302],{"class":1905,"line":5491},[1903,8288,2943],{"class":2037},[1903,8290,1844],{"class":2707},[1903,8292,2903],{"class":1909},[1903,8294,2773],{"class":2602},[1903,8296,6220],{"class":1913},[1903,8298,8299],{"class":2037},">Loading Post details...\u003C/",[1903,8301,1844],{"class":2707},[1903,8303,2711],{"class":2037},[1903,8305,8306],{"class":1905,"line":5497},[1903,8307,8308],{"class":2037},"  {:else}\n",[1903,8310,8311],{"class":1905,"line":5503},[1903,8312,8313],{"class":2037},"    {#if message}\n",[1903,8315,8316,8318,8320,8322,8324,8326,8328,8330],{"class":1905,"line":5513},[1903,8317,3009],{"class":2037},[1903,8319,1844],{"class":2707},[1903,8321,2903],{"class":1909},[1903,8323,2773],{"class":2602},[1903,8325,2952],{"class":1913},[1903,8327,5471],{"class":2037},[1903,8329,1844],{"class":2707},[1903,8331,2711],{"class":2037},[1903,8333,8334,8336,8338],{"class":1905,"line":5527},[1903,8335,6191],{"class":2037},[1903,8337,2968],{"class":2602},[1903,8339,2971],{"class":2037},[1903,8341,8342],{"class":1905,"line":5551},[1903,8343,2699],{"emptyLinePlaceholder":2698},[1903,8345,8346,8348,8350],{"class":1905,"line":5583},[1903,8347,2943],{"class":2037},[1903,8349,2984],{"class":2707},[1903,8351,5510],{"class":2987},[1903,8353,8354,8357,8359,8361,8363],{"class":1905,"line":5593},[1903,8355,8356],{"class":2987},"      \u003Cdiv",[1903,8358,2903],{"class":1909},[1903,8360,2773],{"class":2602},[1903,8362,3001],{"class":1913},[1903,8364,2711],{"class":2037},[1903,8366,8367,8369,8371,8373,8375,8377,8379,8381],{"class":1905,"line":5598},[1903,8368,5601],{"class":2037},[1903,8370,5533],{"class":2707},[1903,8372,5536],{"class":1909},[1903,8374,2773],{"class":2602},[1903,8376,5440],{"class":1913},[1903,8378,7542],{"class":2037},[1903,8380,5533],{"class":2707},[1903,8382,2711],{"class":2037},[1903,8384,8385,8387,8389,8391,8393,8395,8397,8399,8401,8403,8405,8407,8409,8412,8414],{"class":1905,"line":5614},[1903,8386,5601],{"class":2037},[1903,8388,3130],{"class":2707},[1903,8390,2260],{"class":1909},[1903,8392,2773],{"class":2602},[1903,8394,5562],{"class":1913},[1903,8396,5565],{"class":1909},[1903,8398,2773],{"class":2602},[1903,8400,5440],{"class":1913},[1903,8402,3140],{"class":1909},[1903,8404,2047],{"class":2037},[1903,8406,3034],{"class":1909},[1903,8408,2773],{"class":2602},[1903,8410,8411],{"class":2037},"{post.title} ",[1903,8413,7578],{"class":1909},[1903,8415,3163],{"class":2037},[1903,8417,8418,8420,8422],{"class":1905,"line":5635},[1903,8419,5890],{"class":2037},[1903,8421,2900],{"class":2707},[1903,8423,2711],{"class":2037},[1903,8425,8426],{"class":1905,"line":5665},[1903,8427,2699],{"emptyLinePlaceholder":2698},[1903,8429,8430,8432,8434,8436,8438,8440],{"class":1905,"line":5674},[1903,8431,3009],{"class":2037},[1903,8433,2900],{"class":2707},[1903,8435,2903],{"class":1909},[1903,8437,2773],{"class":2602},[1903,8439,3001],{"class":1913},[1903,8441,2711],{"class":2037},[1903,8443,8444,8446,8448,8450,8452,8454,8456,8458],{"class":1905,"line":5679},[1903,8445,5601],{"class":2037},[1903,8447,5533],{"class":2707},[1903,8449,5536],{"class":1909},[1903,8451,2773],{"class":2602},[1903,8453,7619],{"class":1913},[1903,8455,7622],{"class":2037},[1903,8457,5533],{"class":2707},[1903,8459,2711],{"class":2037},[1903,8461,8462,8464,8466,8468,8470,8472,8474,8476,8478,8480,8483,8485,8487,8489,8491,8493,8495],{"class":1905,"line":5694},[1903,8463,5601],{"class":2037},[1903,8465,7633],{"class":2707},[1903,8467,5565],{"class":1909},[1903,8469,2773],{"class":2602},[1903,8471,7619],{"class":1913},[1903,8473,3140],{"class":1909},[1903,8475,2047],{"class":2037},[1903,8477,3034],{"class":1909},[1903,8479,2773],{"class":2602},[1903,8481,8482],{"class":2037},"{post.content} ",[1903,8484,7653],{"class":1909},[1903,8486,2773],{"class":2602},[1903,8488,7658],{"class":1913},[1903,8490,3160],{"class":1909},[1903,8492,7663],{"class":2037},[1903,8494,7633],{"class":2707},[1903,8496,2711],{"class":2037},[1903,8498,8499,8501,8503],{"class":1905,"line":5714},[1903,8500,5890],{"class":2037},[1903,8502,2900],{"class":2707},[1903,8504,2711],{"class":2037},[1903,8506,8507],{"class":1905,"line":5744},[1903,8508,2699],{"emptyLinePlaceholder":2698},[1903,8510,8511,8513,8515,8517,8519,8521],{"class":1905,"line":5753},[1903,8512,3009],{"class":2037},[1903,8514,2900],{"class":2707},[1903,8516,2903],{"class":1909},[1903,8518,2773],{"class":2602},[1903,8520,7088],{"class":1913},[1903,8522,2711],{"class":2037},[1903,8524,8525,8527,8529,8531,8533,8535,8537,8539,8542,8545,8547],{"class":1905,"line":5758},[1903,8526,5601],{"class":2037},[1903,8528,3227],{"class":2707},[1903,8530,2260],{"class":1909},[1903,8532,2773],{"class":2602},[1903,8534,3234],{"class":1913},[1903,8536,2903],{"class":1909},[1903,8538,2773],{"class":2602},[1903,8540,8541],{"class":1913},"\"button save\"",[1903,8543,8544],{"class":2037},">Save Changes\u003C/",[1903,8546,3227],{"class":2707},[1903,8548,2711],{"class":2037},[1903,8550,8551,8553,8555,8557,8559,8561,8563,8565,8568,8571,8573],{"class":1905,"line":5785},[1903,8552,5601],{"class":2037},[1903,8554,1862],{"class":2707},[1903,8556,3278],{"class":1909},[1903,8558,2773],{"class":2602},[1903,8560,4839],{"class":1913},[1903,8562,2903],{"class":1909},[1903,8564,2773],{"class":2602},[1903,8566,8567],{"class":1913},"\"button cancel\"",[1903,8569,8570],{"class":2037},">Cancel\u003C/",[1903,8572,1862],{"class":2707},[1903,8574,2711],{"class":2037},[1903,8576,8577,8579,8581],{"class":1905,"line":5793},[1903,8578,5890],{"class":2037},[1903,8580,2900],{"class":2707},[1903,8582,2711],{"class":2037},[1903,8584,8585,8587,8589],{"class":1905,"line":5804},[1903,8586,3118],{"class":2037},[1903,8588,2984],{"class":2707},[1903,8590,2711],{"class":2037},[1903,8592,8593,8595,8597],{"class":1905,"line":5815},[1903,8594,2965],{"class":2037},[1903,8596,6194],{"class":2602},[1903,8598,2061],{"class":2037},[1903,8600,8601,8603,8605],{"class":1905,"line":5834},[1903,8602,2883],{"class":2602},[1903,8604,2900],{"class":2037},[1903,8606,2711],{"class":2602},[1844,8608,8609,8610,8613,8614,8617,8618,8621],{},"The code snippet above allows a user to edit a post. It first retrieves the blog post details using its ",[1890,8611,8612],{},"id"," and displays the existing data. Once a user makes the necessary edits, the data is updated via the ",[1890,8615,8616],{},"handleSubmit"," function, which sends the updated title and content to the backend through the ",[1890,8619,8620],{},"updateItem"," function.",[1933,8623,8625],{"id":8624},"implement-the-logout-functionality","Implement the Logout Functionality",[1844,8627,8628,8629,1885],{},"The next step involves creating a logout component to enable users to log out. Navigate to  ",[1890,8630,3906],{},[1844,8632,8633],{},"Add the following function:",[1895,8635,8637],{"className":2588,"code":8636,"language":2590,"meta":24,"style":24},"//src/lib/directus.js\nexport const logoutUser = async () => {\n try {\n   await client.logout();\n   console.log(\"Logout successful\");\n   goto(\"/login\");\n } catch (error) {\n   console.error(\"Logout failed:\", error);\n   throw error;\n }\n};\n",[1890,8638,8639,8644,8663,8670,8682,8695,8706,8715,8727,8734,8739],{"__ignoreMap":24},[1903,8640,8641],{"class":1905,"line":1906},[1903,8642,8643],{"class":2178},"//src/lib/directus.js\n",[1903,8645,8646,8648,8650,8653,8655,8657,8659,8661],{"class":1905,"line":1917},[1903,8647,2636],{"class":2602},[1903,8649,2639],{"class":2602},[1903,8651,8652],{"class":1909}," logoutUser",[1903,8654,2626],{"class":2602},[1903,8656,4138],{"class":2602},[1903,8658,4141],{"class":2037},[1903,8660,4144],{"class":2602},[1903,8662,4147],{"class":2037},[1903,8664,8665,8668],{"class":1905,"line":1926},[1903,8666,8667],{"class":2602}," try",[1903,8669,4147],{"class":2037},[1903,8671,8672,8675,8677,8680],{"class":1905,"line":2235},[1903,8673,8674],{"class":2602},"   await",[1903,8676,2779],{"class":2037},[1903,8678,8679],{"class":1909},"logout",[1903,8681,3461],{"class":2037},[1903,8683,8684,8686,8688,8690,8693],{"class":1905,"line":2247},[1903,8685,4635],{"class":2037},[1903,8687,4491],{"class":1909},[1903,8689,2656],{"class":2037},[1903,8691,8692],{"class":1913},"\"Logout successful\"",[1903,8694,2837],{"class":2037},[1903,8696,8697,8700,8702,8704],{"class":1905,"line":2252},[1903,8698,8699],{"class":2602},"   goto",[1903,8701,2656],{"class":2037},[1903,8703,2834],{"class":1913},[1903,8705,2837],{"class":2037},[1903,8707,8708,8711,8713],{"class":1905,"line":2272},[1903,8709,8710],{"class":2037}," } ",[1903,8712,2845],{"class":2602},[1903,8714,4201],{"class":2037},[1903,8716,8717,8719,8721,8723,8725],{"class":1905,"line":2280},[1903,8718,4635],{"class":2037},[1903,8720,4209],{"class":1909},[1903,8722,2656],{"class":2037},[1903,8724,4764],{"class":1913},[1903,8726,4217],{"class":2037},[1903,8728,8729,8732],{"class":1905,"line":2285},[1903,8730,8731],{"class":2602},"   throw",[1903,8733,4553],{"class":2037},[1903,8735,8736],{"class":1905,"line":2297},[1903,8737,8738],{"class":2037}," }\n",[1903,8740,8741],{"class":1905,"line":2302},[1903,8742,4244],{"class":2037},[1844,8744,8745],{},"Once a user logs out, they will redirected back to the login page.",[1933,8747,8749],{"id":8748},"update-the-default-page","Update the Default Page",[1844,8751,8752,8753,8756],{},"Almost done! The next step is to update the default page where the application initializes. Navigate to the ",[1890,8754,8755],{},"./routes/+page.svelte"," file and replace its content with the following code:",[1895,8758,8760],{"className":2588,"code":8759,"language":2590,"meta":24,"style":24},"\u003Cscript>\n  import { onMount } from \"svelte\";\n  import { isAuthenticated } from \"../lib/directus.js\";\n  import { goto } from \"$app/navigation\";\n\n  onMount(async () => {\n    try {\n      const response = await isAuthenticated();\n\n      if (response.authenticated === false) {\n        goto(\"/login\");\n      } else {\n        goto(\"/protected\");\n      }\n    } catch (error) {\n      console.error(\"Authentication check failed:\", error);\n      goto(\"/login\");\n    }\n  });\n\u003C/script>\n\n\u003Cdiv class=\"container\">\n  \u003Ch1>Welcome to the App\u003C/h1>\n  \u003Cp>Redirecting...\u003C/p>\n\u003C/div>\n",[1890,8761,8762,8770,8774,8779,8783,8787,8791,8795,8807,8811,8822,8832,8836,8846,8850,8858,8867,8877,8881,8885,8893,8897,8911,8924,8937],{"__ignoreMap":24},[1903,8763,8764,8766,8768],{"class":1905,"line":1906},[1903,8765,2704],{"class":2037},[1903,8767,2708],{"class":2707},[1903,8769,2711],{"class":2037},[1903,8771,8772],{"class":1905,"line":1917},[1903,8773,4994],{"class":2037},[1903,8775,8776],{"class":1905,"line":1926},[1903,8777,8778],{"class":2037},"  import { isAuthenticated } from \"../lib/directus.js\";\n",[1903,8780,8781],{"class":1905,"line":2235},[1903,8782,2726],{"class":2037},[1903,8784,8785],{"class":1905,"line":2247},[1903,8786,2699],{"emptyLinePlaceholder":2698},[1903,8788,8789],{"class":1905,"line":2252},[1903,8790,5031],{"class":2037},[1903,8792,8793],{"class":1905,"line":2272},[1903,8794,2765],{"class":2037},[1903,8796,8797,8799,8801,8803,8805],{"class":1905,"line":2280},[1903,8798,2770],{"class":2037},[1903,8800,2773],{"class":2602},[1903,8802,2776],{"class":2602},[1903,8804,3458],{"class":1909},[1903,8806,3461],{"class":2037},[1903,8808,8809],{"class":1905,"line":2285},[1903,8810,2699],{"emptyLinePlaceholder":2698},[1903,8812,8813,8815,8818,8820],{"class":1905,"line":2297},[1903,8814,3480],{"class":1909},[1903,8816,8817],{"class":2037}," (response.authenticated === ",[1903,8819,4226],{"class":4318},[1903,8821,4425],{"class":2037},[1903,8823,8824,8826,8828,8830],{"class":1905,"line":2302},[1903,8825,3488],{"class":2602},[1903,8827,2656],{"class":2037},[1903,8829,2834],{"class":1913},[1903,8831,2837],{"class":2037},[1903,8833,8834],{"class":1905,"line":2351},[1903,8835,3500],{"class":2037},[1903,8837,8838,8840,8842,8844],{"class":1905,"line":2359},[1903,8839,3488],{"class":2602},[1903,8841,2656],{"class":2037},[1903,8843,3493],{"class":1913},[1903,8845,2837],{"class":2037},[1903,8847,8848],{"class":1905,"line":2364},[1903,8849,3517],{"class":2037},[1903,8851,8852,8854,8856],{"class":1905,"line":2396},[1903,8853,2842],{"class":2037},[1903,8855,2845],{"class":1909},[1903,8857,4201],{"class":2037},[1903,8859,8860,8862,8865],{"class":1905,"line":2404},[1903,8861,3573],{"class":2037},[1903,8863,8864],{"class":1913},"\"Authentication check failed:\"",[1903,8866,4217],{"class":2037},[1903,8868,8869,8871,8873,8875],{"class":1905,"line":2409},[1903,8870,2829],{"class":1909},[1903,8872,2656],{"class":2037},[1903,8874,2834],{"class":1913},[1903,8876,2837],{"class":2037},[1903,8878,8879],{"class":1905,"line":2423},[1903,8880,2871],{"class":2037},[1903,8882,8883],{"class":1905,"line":2428},[1903,8884,5248],{"class":2037},[1903,8886,8887,8889,8891],{"class":1905,"line":2444},[1903,8888,2883],{"class":2037},[1903,8890,2708],{"class":2707},[1903,8892,2711],{"class":2037},[1903,8894,8895],{"class":1905,"line":2452},[1903,8896,2699],{"emptyLinePlaceholder":2698},[1903,8898,8899,8901,8903,8905,8907,8909],{"class":1905,"line":2469},[1903,8900,2704],{"class":2037},[1903,8902,2900],{"class":2707},[1903,8904,2903],{"class":1909},[1903,8906,2773],{"class":2602},[1903,8908,2908],{"class":1913},[1903,8910,2711],{"class":2037},[1903,8912,8913,8915,8917,8920,8922],{"class":1905,"line":2510},[1903,8914,2916],{"class":2037},[1903,8916,2919],{"class":2707},[1903,8918,8919],{"class":2037},">Welcome to the App\u003C/",[1903,8921,2919],{"class":2707},[1903,8923,2711],{"class":2037},[1903,8925,8926,8928,8930,8933,8935],{"class":1905,"line":2851},[1903,8927,2916],{"class":2037},[1903,8929,1844],{"class":2707},[1903,8931,8932],{"class":2037},">Redirecting...\u003C/",[1903,8934,1844],{"class":2707},[1903,8936,2711],{"class":2037},[1903,8938,8939,8941,8943],{"class":1905,"line":2862},[1903,8940,2883],{"class":2037},[1903,8942,2900],{"class":2707},[1903,8944,2711],{"class":2037},[1840,8946,8948],{"id":8947},"test-the-application","Test the application",[1844,8950,8951],{},"Now, let's test the application. Run this command:",[1895,8953,8955],{"className":1897,"code":8954,"language":1899,"meta":24,"style":24},"npm run dev\n",[1890,8956,8957],{"__ignoreMap":24},[1903,8958,8959,8961,8963],{"class":1905,"line":1906},[1903,8960,2547],{"class":1909},[1903,8962,2521],{"class":1913},[1903,8964,8965],{"class":1913}," dev\n",[1844,8967,2136,8968,8972,8973],{},[1862,8969,8970],{"href":8970,"rel":8971},"http://localhost:5173/",[1866]," on your browser, and you should have a login page displayed:\n",[1971,8974],{"alt":8975,"src":8976},"login page displayed on the browser","/img/login.png",[1844,8978,8979,8980,8983],{},"To register a new user, click on the ",[1987,8981,8982],{},"register here"," link, which redirects you to where you would register. After registering, you can then proceed to log in. Once logged in, you are redirected to the protected page where you can view posts, create new posts, and view your profile:",[1844,8985,8986],{},[1971,8987],{"alt":8988,"src":8989},"image showing the protected page on the browser","/img/protected_page.png",[1844,8991,8992,8993,8996],{},"To create a new post, click on the ",[1987,8994,8995],{},"Create New Posts"," link. It will direct you to the page where you can create a post:",[1844,8998,8999],{},[1971,9000],{"alt":9001,"src":9002},"the page to create a post","/img/create_post.png",[1844,9004,9005],{},"To view posts, click on the view posts where you'll see the posts created:",[1844,9007,9008],{},[1971,9009],{"alt":9010,"src":9011},"Page to view posts","/img/view_post.png",[1844,9013,9014],{},"To view your profile, click on the profile link, and you'll be redirected to the profile page where you can also edit your profile.",[1840,9016,9018],{"id":9017},"conclusion","Conclusion",[1844,9020,9021],{},"Driectus offers you many features, and authentication is just one of them. With Directus authentication, you can secure your web application and ensure that only your users are able to access their data.",[9023,9024,9025],"style",{},"html pre.shiki code .snPdu, html code.shiki .snPdu{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sIIMD, html code.shiki .sIIMD{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sovSZ, html code.shiki .sovSZ{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sPrNH, html code.shiki .sPrNH{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}html pre.shiki code .sP4rz, html code.shiki .sP4rz{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":24,"searchDepth":1906,"depth":1917,"links":9027},[9028,9029,9030,9033,9036,9051,9052],{"id":1842,"depth":1917,"text":130},{"id":1849,"depth":1917,"text":1850},{"id":1877,"depth":1917,"text":1878,"children":9031},[9032],{"id":1935,"depth":1926,"text":1936},{"id":1977,"depth":1917,"text":1978,"children":9034},[9035],{"id":2129,"depth":1926,"text":2130},{"id":2152,"depth":1917,"text":2153,"children":9037},[9038,9039,9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050],{"id":2573,"depth":1926,"text":2574},{"id":2668,"depth":1926,"text":2669},{"id":3317,"depth":1926,"text":3318},{"id":3899,"depth":1926,"text":3900},{"id":3995,"depth":1926,"text":3996},{"id":4080,"depth":1926,"text":4081},{"id":4254,"depth":1926,"text":4255},{"id":4567,"depth":1926,"text":4568},{"id":4946,"depth":1926,"text":4947},{"id":6255,"depth":1926,"text":6256},{"id":7175,"depth":1926,"text":7176},{"id":8624,"depth":1926,"text":8625},{"id":8748,"depth":1926,"text":8749},{"id":8947,"depth":1917,"text":8948},{"id":9017,"depth":1917,"text":9018},"md",{"slug":9055},"using-authentication-in-sveltekit","---\nslug: using-authentication-in-sveltekit\ntitle: Using Authentication in SvelteKit\ntechnologies:\n  - sveltekit\nauthors:\n  - name: Temitope Oyedelde\n    title: Guest Author\ndescription: Learn how to setup Directus authentication with SvelteKit.\n---\n\n## Introduction\nAuthentication is a critical part of any modern web application. It ensures that users can securely access their data and perform authorized actions. In this tutorial, you will learn how to implement authentication in your SvelteKit application using Directus' built-in authentication system.\n\n## Before You Start\nBefore you proceed, you will need the following:\n\n- A [Directus project](https://directus.io/docs/) with admin access.\n- Fundamental understanding of Svelte.\n- Optional but recommended: Familiarity with data modeling in Directus.\n\n## Set Up Your Directus Project\nIn this tutorial, Docker will be used for this setup. To get started, follow the [Docker setup instructions](/getting-started/create-a-project).\n\nYou also need to make sure to configure CORS. Update your `docker-compose.yml` file as follows:\n\n```bash\n   CORS_ENABLED: \"true\"\n   CORS_ORIGIN: \"http://localhost:5173\"\n   CORS_CREDENTIALS: \"true\"\n```\n\n### Create a Collection\n\nCreate a new collection called `posts` with the `user_created` optional field and the following custom fields:\n\n- `title` (Type: String)\n- `content` (Type: Markdown)\n- `author` (Type: User)\n\n![Post Collection](/img/post_collection.png)\n\n## Configure Roles, Policies, and Permissions\n\nCreate a new role called `Authenticated User` in the **User Roles** section. In this role, you will create a number of policies. \n\nFirst, create a policy and name it `Can Read and Create Posts`. Select the **posts** collection to set some permissions. Set the **Read** permission to **Allow Access** in the options. You also need to set **Create** permission to custom by clicking **Use Custom** in the options, and in the  **Field Permissions**, uncheck `author` so the user cannot set any value. Then, in the **Field Presets**, add the following value to set the value automatically:\n  \n```bash\n{\n    \"author\": \"$CURRENT_USER\"\n}\n```\n\nCreate another policy and name it  `Can Edit and Delete Own Posts`. Also, select the **posts** collection to set some permissions. Set the **Update** permission to custom by clicking **Use Custom** in the options, and in the **Item Permissions**,  set `user_created` to `$CURRENT_USER` to only allow update actions for items created by the currently authenticated user. You also need to do the same thing for **Delete Permissions**\n\nThe last policy to create is a policy named `Can View and Edit Own Profile`. This time the permissions will be set for the `directus_users` collection. Set the **Read** to custom by clciking **Use Custom**. In the **Item Permissions**, set id to `$CURRENT_USER` to only allow users to view their own profile. Also ensure to tick all the required fields in the **Field Permission** section.\n\nDo the same thing for *Update** permission (use the same Item Permissions as Read)\n\nFor each policy you create, ensure that app access is enabled. App access auto-configures minimum permissions required to log in to the App.\n\n### Enable Public Registration\nPublic registration allows any user to create a user in your Directus project directly from the Data Studio or via API.\n\nNavigate to **Project Settings -> User Registration** and enable the setting. Set the default role to 'Authenticated User'.\n\n![Enable user registration](/img/user_registration_directus.png)\n\n This role will automatically be assigned to new users, and it gives them all of the permissions you set up in the previous step.\n\n## Set Up Your SvelteKit Project\nTo start building, you need to install SvelteKit and Directus sdk. Run this command:\n\n```bash\nnpx sv create directus-auth # choose SvelteKit minimal\n```\nWhen prompted, select SvelteKit minimal as the template. Do not add type checking, as this tutorial is implemented using JavaScript. Your output should look like this:\n\n```bash\n Welcome to the Svelte CLI! (v0.6.16)\n│\n◇  Which template would you like?\n│  SvelteKit minimal\n│\n◇  Add type checking with Typescript?\n│  No\n│\n◆  Project created\n│\n◇  What would you like to add to your project? (use arrow keys / space bar)\n│  none\n│\n◇  Which package manager do you want to install dependencies with?\n│  npm\n│\n◆  Successfully installed dependencies\n│\n◇  Project next steps ─────────────────────────────────────────────────────╮\n│                                                                          │\n│  1: cd preview-app                                                       │\n│  2: git init && git add -A && git commit -m \"Initial commit\" (optional)  │\n│  3: npm run dev -- --open\n```\n\nAfterwards, `cd` into your project directory and run:\n\n```bash\nnpm install\n```\n\nThis will install all the dependencies for the project.\n\n\nLastly, you need to install the Directus SDK. Run this command:\n\n```bash\nnpm install @directus/sdk\n```\n### Configure the Directus SDK\n\nYou need to configure Directus SDK in your project. Create a file called `directus.js` inside the `./src/lib` directory. Add the following code:\n\n```javascript\n// src/lib/directus.js\nimport { createDirectus, rest } from \"@directus/sdk\";\nconst directusUrl = \"http://localhost:8055\";\nexport const client = createDirectus(directusUrl).with(rest());\n```\n\nThis setups Directus client with the authentication composable. And will be updated as we progress in the tutorial.\n\n### Implement User Registration\n\nIn the following step, you will create a component to handle registering user and save their credentials on the Directus backend. Create a subdirectory called `register` inside the `./src/routes` directory, and inside it, create a file `+page.svelte` file, with the following code:\n\n```javascript\n// src/routes/register/+page.svelte\n\n\u003Cscript>\n  import { client } from \"../../lib/directus\";\n  import { registerUser } from \"@directus/sdk\";\n  import { goto } from \"$app/navigation\";\n  let email = \"\";\n  let password = \"\";\n  let firstName = \"\";\n  let lastName = \"\";\n  let error = null;\n\n  async function handleRegister() {\n    try {\n      const response = await client.request(\n        registerUser(email, password, {\n          first_name: firstName,\n          last_name: lastName,\n        })\n      );\n      console.log(\"response>>>>>\", response);\n      goto(\"/login\");\n    } catch (err) {\n      error = err.message;\n      console.error(err);\n    }\n  }\n\u003C/script>\n\n\u003Cdiv class=\"container\">\n  \u003Ch1>Create Account\u003C/h1>\n\n  {#if error}\n    \u003Cp class=\"error\">{error}\u003C/p>\n  {/if}\n\n  \u003Cform on:submit|preventDefault={handleRegister}>\n    \u003Cdiv class=\"form-group\">\n      \u003Cinput\n        type=\"text\"\n        bind:value={firstName}\n        placeholder=\"First Name\"\n        required\n      />\n      \u003Cinput\n        type=\"text\"\n        bind:value={lastName}\n        placeholder=\"Last Name\"\n        required\n      />\n    \u003C/div>\n    \u003Cinput type=\"email\" bind:value={email} placeholder=\"Email\" required />\n    \u003Cinput\n      type=\"password\"\n      bind:value={password}\n      placeholder=\"Password\"\n      required\n    />\n    \u003Cbutton type=\"submit\">Register\u003C/button>\n  \u003C/form>\n  \u003Cp class=\"login-link\">\n    Already have an account? \u003Ca href=\"/login\">Login here\u003C/a>\n  \u003C/p>\n\u003C/div>\n```\nThe above code snippet is a form that collects the user's credentials, which are the name, email, and password, submits it, and sends a request to the Directus server via the `handleRegister` function. If the registration is successful, the user is then redirected to the login page, which will be created below.\n\n### Implement User Login\n\nIn the following step, you will create a login component where the users will be directed to log in. Create a subdirectory called `login` inside the `./src/routes` directory, and inside it, create a file `+page.svelte` file with the following code:\n\n```javascript\n\u003C!-- src/routes/login/+page.svelte -->\n\u003Cscript>\n  import { client, isAuthenticated } from \"../../lib/directus.js\";\n  import { goto } from \"$app/navigation\";\n\n  let email = \"\";\n  let password = \"\";\n  let error = null;\n\n  async function handleLogin() {\n    try {\n      // Call the login method directly from the client\n      const result = await client.login({ email, password });\n      console.log(\"Login successful:\", result);\n\n      // Check if the user is authenticated\n      const authStatus = await isAuthenticated();\n      console.log(\"Authentication status:\", authStatus);\n\n      if (authStatus.authenticated) {\n        goto(\"/protected\");\n      } else {\n        error = \"Failed to authenticate. Please try again.\";\n      }\n    } catch (err) {\n      if (err.response?.status === 403) {\n        error = \"Invalid email or password.\";\n      } else {\n        error = err.message || \"Login failed.\";\n      }\n      console.error(\"Login error:\", err);\n    }\n  }\n\u003C/script>\n\n\u003Cdiv>\n  \u003Ch1 style=\"color: #000;\">Welcome Back\u003C/h1>\n\n  {#if error}\n    \u003Cdiv>\n      \u003Cp>{error}\u003C/p>\n    \u003C/div>\n  {/if}\n\n  \u003Cform on:submit|preventDefault={handleLogin}>\n    \u003Cdiv>\n      \u003Cinput\n        type=\"email\"\n        bind:value={email}\n        placeholder=\"Email\"\n        required\n        autocomplete=\"email\"\n      />\n    \u003C/div>\n    \u003Cdiv>\n      \u003Cinput\n        type=\"password\"\n        bind:value={password}\n        placeholder=\"Password\"\n        required\n      />\n    \u003C/div>\n    \u003Cbutton type=\"submit\">Sign In\u003C/button>\n  \u003C/form>\n\n  \u003Cp style=\"color: #000;\">\n    Don't have an account? \u003Ca href=\"/register\">Register here\u003C/a>\n  \u003C/p>\n\u003C/div>\n```\n\n### Json Authentcation mode\nJson Authentication mode is one of the two approaches Directus offers to authentication. It involves the server returning an access token and a refresh token in the response body during authentication. To use the json mode, update your authentication composable in your `./src/lib/directus.js` file to this:\n\n```javascript\n// src/lib/directus.js\n\nimport {createDirectus, rest,authentication} from \"@directus/sdk\";\nconst directusUrl = \"http://localhost:8055\";\nexport const client = createDirectus(directusUrl)\n .with(authentication(\"json\"))\n .with(rest());\n```\n\n### Session Cookie Authentication Mode\n\nThe session cookies authentication mode is a simpler way provided by Directus if you do not want to manage authentication in your local storage. Directus client retrieves the tokens and stores them as cookies in your browser session. To use the cookie mode, update your authentication composable in your `./src/lib/directus.js` file to this:\n\n```javascript\n// src/lib/directus.js\nimport {createDirectus, rest,authentication} from \"@directus/sdk\";\nconst directusUrl = \"http://localhost:8055\";\nexport const client = createDirectus(directusUrl)\n .with(authentication(\"cookie\"))\n .with(rest());\n```\n\n### Check if the User is Authenticated\n\nThe next thing you want to do is to perform an authentication check to see if the user is authenticated by attempting to fetch their information using the Directus client.\n\n Add the following function to the `src/lib/directus.js` file:\n\n```javascript\n// src/lib/directus.js\n\nimport { readMe } from \"@directus/sdk\";\n\n\nexport const isAuthenticated = async () => {\n  try {\n    const user = await client.request(readMe());\n    return { authenticated: !!user?.id, user };\n  } catch (error) {\n    console.error(\"Error checking authentication:\", error);\n    return { authenticated: false, user: null };\n  }\n};\n```\n\nThe code snippet above makes a request using `client.request(readMe())` to try to get the current user's information\nand checks if that request returns a user with an ID. It also returns whether authentication was successful based on whether that user data exists.\n\n### Refreshing Tokens\nAs access tokens expire after a set time period, you'll need to refresh them and that's where the `refreshAccessToken` function comes in. It will handle token renewal for both cookie-based and JSON-based authentication modes.\n\nAdd this function right after the `isAuthentcated` function:\n\n```javascript\n// src/lib/directus.js\n\nimport { refresh } from \"@directus/sdk\";\n\nexport const refreshToken = async (mode = \"json\", refreshToken = null) => {\n  try {\n    let result;\n\n    if (mode === \"json\" && refreshToken) {\n     \n      result = await client.request({ mode: \"json\", refreshToken }));\n    } else if (mode === \"cookie\") {\n      // Use cookie-based refresh\n      result = await client.request(refresh({ mode: \"cookie\" }));\n    } else {\n      result = await client.refresh();\n    }\n\n    console.log(\"Token refreshed successfully\");\n    return {\n      access_token: result.access_token,\n      expires: result.expires,\n      refresh_token: result.refresh_token,\n    };\n  } catch (error) {\n    console.error(\"Token refresh failed:\", error);\n    throw error;\n  }\n};\n```\n\nThe code above uses the provided refresh token to explicitly request a new access token for json mode while it handles refresh through cookies without needing an explicit refresh token for cookie mode.\n\n### Create the Protected Page\nCreate a subdirectory inside the `./src/routes` directory called `protected`. Inside this directory, create a `+page.svelte` inside it.  \n\nAdd the following code:\n\n ```javascript\n// src/routes/protected/+page.svelte\n\n\u003Cscript>\n  import { onMount } from \"svelte\";\n  import { isAuthenticated, logoutUser } from \"../../lib/directus.js\";\n  import { goto } from \"$app/navigation\";\n\n  onMount(async () => {\n    console.log(\"onMount\");\n    const isAuth = await isAuthenticated();\n    console.log(\"isAuth\", isAuth);\n\n    if (isAuth.authenticated === false) {\n      goto(\"/login\");\n    }\n  });\n\n  const handleLogout = async () => {\n    try {\n      await logoutUser(); \n      goto(\"/login\"); \n    } catch (error) {\n      console.error(\"Logout failed:\", error);\n    }\n  };\n\u003C/script>\n\n\u003Ch1>Protected Page\u003C/h1>\n\u003Cp>Welcome! You are logged in.\u003C/p>\n\n\u003Cnav>\n  \u003Ca href=\"/protected/posts\" class=\"nav-link\">View Posts\u003C/a>\n  \u003Ca href=\"/protected/posts/create\" class=\"nav-link\">Create New Posts\u003C/a>\n  \u003Ca href=\"/protected/profile\" class=\"nav-link\">Profile\u003C/a>\n\u003C/nav>\n\n\u003Cbutton on:click={handleLogout}>Logout\u003C/button>\n```\n\nThis page contains the navigation links to other protected resources and a logout button.\n\n### Create the Profile Page\n\nCreate a subdirectory called `profile` inside the  `./src/routes/protected` directory and create a `+page.svelte` file inside it with the following contents:\n\n```javascript\n// src/routes/protected/profile/+page.svelte\n\u003Cscript>\n  import { client, isAuthenticated } from \"../../../lib/directus.js\";\n  import { readMe, updateMe } from \"@directus/sdk\";\n  import { onMount } from \"svelte\";\n  import { goto } from \"$app/navigation\";\n\n  let userData = null;\n  let isEditing = false;\n  let formData = {};\n  let message = \"\";\n\n  onMount(async () => {\n    console.log(\"onMount\");\n\n    // Check if the user is authenticated\n    const isAuth = await isAuthenticated();\n    console.log(\"isAuth\", isAuth);\n\n    if (isAuth.authenticated === false) {\n      goto(\"/login\"); \n      return;\n    }\n\n    // Fetch user profile data using Directus SDK\n    try {\n      const response = await client.request(readMe());\n      console.log(\"ress>>>\", response);\n      userData = {\n        id: response.id,\n        firstName: response.first_name,\n        lastName: response.last_name,\n        email: response.email,\n      };\n      console.log(\"userData>>>>>>\", userData);\n      formData = { ...userData };\n    } catch (error) {\n      console.error(\"Failed to fetch user data:\", error);\n      goto(\"/login\"); \n    }\n  });\n\n  async function handleSubmit() {\n    console.log(\"formData>>>>>>\", formData);\n    try {\n      const response = await client.request(\n        updateMe({\n          first_name: formData.firstName,\n          last_name: formData.lastName,\n          email: formData.email,\n        })\n      );\n      console.log(\"response>>>>>>\", response);\n      message = \"Profile updated successfully!\";\n      isEditing = false;\n      userData = { ...formData };\n    } catch (error) {\n      console.error(\"Error updating profile:\", error);\n      message = \"Failed to update profile. Please try again.\";\n    }\n  }\n\u003C/script>\n\n\u003Cdiv class=\"container\">\n  \u003Ch1 class=\"title\">Profile\u003C/h1>\n\n  {#if message}\n    \u003Cdiv class=\"message\">{message}\u003C/div>\n  {/if}\n\n  {#if userData}\n    {#if isEditing}\n      \u003Cform on:submit|preventDefault={handleSubmit}>\n        \u003Cdiv class=\"form-group\">\n          \u003Clabel for=\"first_name\">First Name\u003C/label>\n          \u003Cinput type=\"text\" id=\"first_name\" bind:value={formData.firstName} />\n        \u003C/div>\n\n        \u003Cdiv class=\"form-group\">\n          \u003Clabel for=\"last_name\">Last Name\u003C/label>\n          \u003Cinput type=\"text\" id=\"last_name\" bind:value={formData.lastName} />\n        \u003C/div>\n\n        \u003Cdiv class=\"form-group\">\n          \u003Clabel for=\"email\">Email\u003C/label>\n          \u003Cinput type=\"email\" id=\"email\" bind:value={formData.email} />\n        \u003C/div>\n\n        \u003Cbutton type=\"submit\" class=\"primary\">Save\u003C/button>\n        \u003Cbutton\n          type=\"button\"\n          class=\"secondary\"\n          on:click={() => {\n            isEditing = false;\n            formData = { ...userData };\n          }}\n        >\n          Cancel\n        \u003C/button>\n      \u003C/form>\n    {:else}\n      \u003Cdiv class=\"profile-info\">\n        \u003Cdiv class=\"profile-field\">\n          \u003Cspan class=\"field-label\">First Name\u003C/span>\n          \u003Cspan style=\"color: #000;\">{userData?.firstName || \"Not set\"}\u003C/span>\n        \u003C/div>\n        \u003Cdiv class=\"profile-field\">\n          \u003Cspan class=\"field-label\">Last Name\u003C/span>\n          \u003Cspan style=\"color: #000;\">{userData.lastName || \"Not set\"}\u003C/span>\n        \u003C/div>\n        \u003Cdiv class=\"profile-field\">\n          \u003Cspan class=\"field-label\">Email\u003C/span>\n          \u003Cspan style=\"color: #000;\">{userData.email}\u003C/span>\n        \u003C/div>\n        \u003Cbutton class=\"primary\" on:click={() => (isEditing = true)}>\n          Edit Profile\n        \u003C/button>\n      \u003C/div>\n    {/if}\n  {:else}\n    \u003Cdiv class=\"loading\">Loading...\u003C/div>\n  {/if}\n\u003C/div>\n```\nThis displays a user profile page where users can view and update their profile details. Upon loading, it verifies authentication and fetches the user's profile data using Directus SDK's `readMe()` function. If not authenticated, it redirects to the login page. \n\n### Create Post Page\nFor the next step, you will create a page that fetches the posts from the Directus server and displays them inside this page, which will act as the page for displaying posts. \n\nCreate a subdirectory called `posts` inside the `./src/routes/protected` directory and create a `+page.svelte` file with the following contents:\n\n```javascript\n// src/routes/protected/posts/+page.svelte\n\n\u003Cscript>\n  import { readItems, deleteItem, readMe } from \"@directus/sdk\";\n  import { onMount } from \"svelte\";\n  import { client, isAuthenticated } from \"../../../lib/directus.js\";\n  import { goto } from \"$app/navigation\";\n\n  let posts = [];\n  let errorMessage = \"\";\n  let currentUserId = { id: null };\n\n  async function deletePost(id) {\n    if (confirm(\"Are you sure you want to delete this post?\")) {\n      try {\n        // Delete the post using Directus SDK\n        await client.request(deleteItem(\"posts\", id));\n        posts = posts.filter((post) => post.id !== id); // Remove the post from the list\n        errorMessage = \"\";\n      } catch (error) {\n        console.error(\"Error deleting post:\", error);\n        errorMessage = \"Failed to delete post. Please try again.\";\n      }\n    }\n  }\n\n  onMount(async () => {\n    console.log(\"onMount\");\n\n    // Check if the user is authenticated\n    const isAuth = await isAuthenticated();\n    console.log(\"isAuth\", isAuth);\n\n    if (isAuth.authenticated === false) {\n      goto(\"/login\"); // Redirect to login if not authenticated\n      return;\n    }\n\n    try {\n      // Fetch all posts using Directus SDK\n      const response = await client.request(readItems(\"posts\"));\n      posts = response;\n      console.log(\"posts\", posts);\n\n      // Fetch the current user ID\n      currentUserId = await client.request(readMe({ fields: [\"id\"] }));\n      console.log(\"Current user:\", currentUserId);\n\n      errorMessage = \"\";\n    } catch (error) {\n      console.error(\"Error fetching posts:\", error);\n      errorMessage = \"Failed to load posts. Please refresh the page.\";\n    }\n  });\n\u003C/script>\n\n\u003Ch1>My Posts\u003C/h1>\n\n{#if errorMessage}\n  \u003Cdiv class=\"error-message\">{errorMessage}\u003C/div>\n{/if}\n\n{#if posts.length > 0}\n  \u003Cdiv class=\"post-grid\">\n    {#each posts as post}\n      \u003Cdiv class=\"post-card\">\n        \u003Ch2>{post.title}\u003C/h2>\n        \u003Cp>{post.content.substring(0, 100)}...\u003C/p>\n\n        \u003Cdiv class=\"card-actions\">\n          {#if post.author === currentUserId?.id}\n            \u003Ca href=\"/protected/posts/{post.id}/edit\" class=\"button edit\">Edit\u003C/a>\n            \u003Cbutton class=\"button delete\" on:click={() => deletePost(post.id)}>Delete\u003C/button>\n          {/if}\n        \u003C/div>\n      \u003C/div>\n    {/each}\n  \u003C/div>\n{:else}\n  \u003Cp class=\"no-posts\">No posts found. Why not create one?\u003C/p>\n{/if}\n\n\u003Cdiv class=\"actions\">\n  \u003Ca href=\"/protected/posts/create\" class=\"button create\">Create New Post\u003C/a>\n  \u003Ca href=\"/protected\" class=\"button back\">Back to Dashboard\u003C/a>\n\u003C/div>\n```\n\nThe code snippet above acts as the page where you can view and delete posts. It also includes a navigation where you can edit your post (which will be created soon).\n\nIt retrieves a list of posts from the Directus backend using the `unMount` function. This function utilizes the Directus SDK by calling `client.request(readItems('posts'))`. Also, a user can delete posts through the `deleteBlog(id)` function which also uses the Directus SDK method to delete a specific blog by its ID from the 'posts' collection within Directus by calling `client.request(deleteItem('posts', id))`.\"\n\n### Implement the Create and Edit Page\n\nThe post page should also allow users to create and edit posts.\n\nTo implement the page to create a post, create a subdirectory called `create` inside the `./src/routes/protected/posts` directory. Create a `+page.svelte` file inside it with the following code:\n\n```javascript\n// src/routes/protected/posts/create/+page.svelte\n\n\u003Cscript>\n  import { createItem } from \"@directus/sdk\";\n  import { goto } from \"$app/navigation\";\n  import { client, isAuthenticated } from \"../../../../lib/directus.js\";\n  import { onMount } from \"svelte\";\n\n  let title = \"\";\n  let content = \"\";\n  let userId;\n\n  onMount(async () => {\n    console.log(\"onMount\");\n\n    const isAuth = await isAuthenticated();\n    console.log(\"isAuth\", isAuth);\n\n    if (isAuth.authenticated === false) {\n      goto(\"/login\"); // Redirect to login if the user is not authenticated\n    } else {\n      userId = isAuth.user.id; // Get the logged-in user ID\n      console.log(\"userId\", userId);\n    }\n  });\n\n  async function handleSubmit() {\n    try {\n  \n      const response = await client.request(\n        createItem(\"posts\", {\n          title,\n          content,\n        })\n      );\n      console.log(\"response\", response);\n\n      // Redirect to the posts list after successful post creation\n      goto(\"/protected/posts\");\n    } catch (error) {\n      console.error(\"Error creating post:\", error);\n    }\n  }\n\u003C/script>\n\n\u003Ch1>Create New Post\u003C/h1>\n\n\u003Cform on:submit|preventDefault={handleSubmit}>\n  \u003Cdiv class=\"form-group\">\n    \u003Clabel for=\"title\">Title\u003C/label>\n    \u003Cinput id=\"title\" type=\"text\" bind:value={title} required />\n  \u003C/div>\n\n  \u003Cdiv class=\"form-group\">\n    \u003Clabel for=\"content\">Content\u003C/label>\n    \u003Ctextarea id=\"content\" bind:value={content} rows=\"10\" required>\u003C/textarea>\n  \u003C/div>\n\n  \u003Cbutton type=\"submit\" class=\"primary\">Create Post\u003C/button>\n\u003C/form>\n\n\u003Ca href=\"/protected/posts\" class=\"back-link\">Back to Posts\u003C/a>\n```\n\nThe code above is used to create a new post. It captures the user input for the post title and content and sends the data to the backend using `createItem`.\n\nTo edit a post, create a subdirectory called `[id]` inside the `./src/routes/protected/posts` directory. Inside it, create another subdirectory called `edit`, and afterward, create a `+page.svelte` file with the following code:\n\n```javascript\n//  src/routes/protected/posts/[id]/edit/+page.svelte\n\u003Cscript>\n  import { readItem, updateItem } from \"@directus/sdk\";\n  import { client, isAuthenticated } from \"../../../../../lib/directus.js\";\n  import { goto } from \"$app/navigation\";\n  import { page } from \"$app/stores\";\n  import { onMount } from \"svelte\";\n\n  const postId = $page.params.id; \n  let isLoading = true;\n  let message = \"\";\n\n  let post = {\n    title: \"\",\n    content: \"\",\n  };\n\n  onMount(async () => {\n    const isAuth = await isAuthenticated();\n    console.log(\"isAuth\", isAuth);\n\n    if (isAuth.authenticated === false) {\n      goto(\"/login\"); \n      return;\n    }\n\n    await loadPost();\n  });\n\n  async function loadPost() {\n    isLoading = true; \n    try {\n      const response = await client.request(readItem(\"posts\", postId));\n      if (\n        response &&\n        typeof response.title === \"string\" &&\n        typeof response.content === \"string\"\n      ) {\n        post = { title: response.title, content: response.content };\n      }\n    } catch (error) {\n      console.error(\"Error fetching post:\", error);\n      message = \"Failed to load post details. Please try again.\";\n    }\n    isLoading = false;\n  }\n\n  async function handleSubmit() {\n    isLoading = true; \n    try {\n      // Update the post using the Directus SDK\n      await client.request(\n        updateItem(\"posts\", postId, {\n          title: post.title,\n          content: post.content,\n        })\n      );\n      goto(\"/protected/posts\"); \n    } catch (error) {\n      console.error(\"Error updating post:\", error);\n      message = \"Failed to update post. Please try again.\";\n    }\n    isLoading = false;\n  }\n\u003C/script>\n\n\u003Cdiv class=\"edit-container\">\n  \u003Ch1>Edit Post\u003C/h1>\n\n  {#if isLoading}\n    \u003Cp class=\"loading\">Loading Post details...\u003C/p>\n  {:else}\n    {#if message}\n      \u003Cp class=\"error\">{message}\u003C/p>\n    {/if}\n\n    \u003Cform on:submit|preventDefault={handleSubmit}>\n      \u003Cdiv class=\"form-group\">\n        \u003Clabel for=\"title\">Title\u003C/label>\n        \u003Cinput type=\"text\" id=\"title\" bind:value={post.title} required />\n      \u003C/div>\n\n      \u003Cdiv class=\"form-group\">\n        \u003Clabel for=\"content\">Content\u003C/label>\n        \u003Ctextarea id=\"content\" bind:value={post.content} rows=\"10\" required>\u003C/textarea>\n      \u003C/div>\n\n      \u003Cdiv class=\"actions\">\n        \u003Cbutton type=\"submit\" class=\"button save\">Save Changes\u003C/button>\n        \u003Ca href=\"/protected/posts\" class=\"button cancel\">Cancel\u003C/a>\n      \u003C/div>\n    \u003C/form>\n  {/if}\n\u003C/div>\n```\n\nThe code snippet above allows a user to edit a post. It first retrieves the blog post details using its `id` and displays the existing data. Once a user makes the necessary edits, the data is updated via the `handleSubmit` function, which sends the updated title and content to the backend through the `updateItem` function.\n\n### Implement the Logout Functionality\nThe next step involves creating a logout component to enable users to log out. Navigate to  `./src/lib/directus.js`. \n\nAdd the following function:\n\n ```javascript\n//src/lib/directus.js\nexport const logoutUser = async () => {\n  try {\n    await client.logout();\n    console.log(\"Logout successful\");\n    goto(\"/login\");\n  } catch (error) {\n    console.error(\"Logout failed:\", error);\n    throw error;\n  }\n};\n```\nOnce a user logs out, they will redirected back to the login page.\n\n### Update the Default Page\n\nAlmost done! The next step is to update the default page where the application initializes. Navigate to the `./routes/+page.svelte` file and replace its content with the following code:\n\n```javascript\n\u003Cscript>\n  import { onMount } from \"svelte\";\n  import { isAuthenticated } from \"../lib/directus.js\";\n  import { goto } from \"$app/navigation\";\n\n  onMount(async () => {\n    try {\n      const response = await isAuthenticated();\n\n      if (response.authenticated === false) {\n        goto(\"/login\");\n      } else {\n        goto(\"/protected\");\n      }\n    } catch (error) {\n      console.error(\"Authentication check failed:\", error);\n      goto(\"/login\");\n    }\n  });\n\u003C/script>\n\n\u003Cdiv class=\"container\">\n  \u003Ch1>Welcome to the App\u003C/h1>\n  \u003Cp>Redirecting...\u003C/p>\n\u003C/div>\n```\n\n## Test the application\nNow, let's test the application. Run this command:\n\n```bash\nnpm run dev\n```\n\nNavigate to http://localhost:5173/ on your browser, and you should have a login page displayed:\n![login page displayed on the browser](/img/login.png)\n\nTo register a new user, click on the **register here** link, which redirects you to where you would register. After registering, you can then proceed to log in. Once logged in, you are redirected to the protected page where you can view posts, create new posts, and view your profile:\n\n![image showing the protected page on the browser](/img/protected_page.png)\n\nTo create a new post, click on the **Create New Posts** link. It will direct you to the page where you can create a post:\n\n![the page to create a post](/img/create_post.png)\n\nTo view posts, click on the view posts where you'll see the posts created:\n\n![Page to view posts](/img/view_post.png)\n\nTo view your profile, click on the profile link, and you'll be redirected to the profile page where you can also edit your profile.\n\n## Conclusion\nDriectus offers you many features, and authentication is just one of them. With Directus authentication, you can secure your web application and ensure that only your users are able to access their data.\n",{"title":1366,"description":1369},[9059],"sveltekit","xG3E54QBMadp0NVDLK7p4JE__B7KbuJYE3klE_F2nPc",1775038774065]