From 7a46300c9bb7c5aac052783947e757e77c43ec3d Mon Sep 17 00:00:00 2001 From: kheiner Date: Sat, 25 Apr 2026 11:32:48 -0700 Subject: [PATCH 1/4] docs: improve clarity for typescript + sdk Update the language in callout to better represent linked content. --- content/guides/04.connect/6.sdk.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/guides/04.connect/6.sdk.md b/content/guides/04.connect/6.sdk.md index 8e432b01e..bf04b58d8 100644 --- a/content/guides/04.connect/6.sdk.md +++ b/content/guides/04.connect/6.sdk.md @@ -55,7 +55,7 @@ The Directus SDK is a "Composable Client" that allows you to customize and build ``` ::callout{icon="material-symbols:school-outline" color="secondary" to="/tutorials/tips-and-tricks/advanced-types-with-the-directus-sdk"} - Learn how to create a Schema for SDK client creation. + Learn how to take advantage of TypeScript while using the SDK. :: From e01fa44efab430ed701763711a27d59195e68e25 Mon Sep 17 00:00:00 2001 From: judda <44623501+ComfortablyCoding@users.noreply.github.com> Date: Fri, 5 Jun 2026 16:48:28 -0400 Subject: [PATCH 2/4] Apply suggestion from @ComfortablyCoding --- content/guides/04.connect/6.sdk.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/guides/04.connect/6.sdk.md b/content/guides/04.connect/6.sdk.md index bf04b58d8..d967d559f 100644 --- a/content/guides/04.connect/6.sdk.md +++ b/content/guides/04.connect/6.sdk.md @@ -55,7 +55,7 @@ The Directus SDK is a "Composable Client" that allows you to customize and build ``` ::callout{icon="material-symbols:school-outline" color="secondary" to="/tutorials/tips-and-tricks/advanced-types-with-the-directus-sdk"} - Learn how to take advantage of TypeScript while using the SDK. + Learn how to leverage TypeScript with the SDK for auto-completion and generated output types. :: From de90d9a9eda81370271cebcac8fb639448efe3ec Mon Sep 17 00:00:00 2001 From: daedalus <44623501+ComfortablyCoding@users.noreply.github.com> Date: Fri, 5 Jun 2026 16:51:09 -0400 Subject: [PATCH 3/4] remove fmt --- content/guides/04.connect/6.sdk.md | 340 ++++++++++++----------------- 1 file changed, 145 insertions(+), 195 deletions(-) diff --git a/content/guides/04.connect/6.sdk.md b/content/guides/04.connect/6.sdk.md index ca407feba..98b139561 100644 --- a/content/guides/04.connect/6.sdk.md +++ b/content/guides/04.connect/6.sdk.md @@ -23,76 +23,66 @@ The Directus SDK is a "Composable Client" that allows you to customize and build | `staticToken()` | Adds `.setToken()` and `.getToken()` methods for manually managing tokens. | ::tabs -::div{class="pr-6"} - ---- - -label: JavaScript - ---- + ::div{class="pr-6"} + --- + label: JavaScript + --- + ```js + import { createDirectus, rest } from '@directus/sdk'; + const directus = createDirectus('http://directus.example.com').with(rest()); + ``` + :: + + ::div{class="pr-6"} + --- + label: TypeScript + --- + You must provide a `Schema` when creating a Directus client to make use of type hinting and completion. This schema contains definitions for each collection and provides you with type hints (on input) and completion (on output). + + ```ts + import { createDirectus, rest } from '@directus/sdk'; + + interface Post { + id: number; + title: string; + content: string; + } -```js -import { createDirectus, rest } from "@directus/sdk"; -const directus = createDirectus("http://directus.example.com").with(rest()); -``` + interface Schema { + posts: Post[]; + } + const directus = createDirectus('http://directus.example.com').with(rest()); + ``` :: -::div{class="pr-6"} - ---- - -label: TypeScript - ---- - -You must provide a `Schema` when creating a Directus client to make use of type hinting and completion. This schema contains definitions for each collection and provides you with type hints (on input) and completion (on output). - -```ts -import { createDirectus, rest } from "@directus/sdk"; - -interface Post { - id: number; - title: string; - content: string; -} - -interface Schema { - posts: Post[]; -} - -const directus = createDirectus("http://directus.example.com").with( - rest(), -); -``` - ::callout{icon="i-lucide-graduation-cap" color="secondary" to="/tutorials/tips-and-tricks/advanced-types-with-the-directus-sdk"} -Learn how to leverage TypeScript with the SDK for auto-completion and generated output types. + Learn how to leverage TypeScript with the SDK for auto-completion and generated output types. :: + ## Making Requests To make a request, you must create the client with the `rest()` or `graphql()` composable. If using `rest()`, you must also import and use one of the query functions. ```js -import { createDirectus, rest, readItems } from "@directus/sdk"; -const directus = createDirectus("http://directus.example.com").with(rest()); +import { createDirectus, rest, readItems } from '@directus/sdk'; +const directus = createDirectus('http://directus.example.com').with(rest()); -const allPosts = await directus.request(readItems("posts")); +const allPosts = await directus.request(readItems('posts')); const somePosts = await directus.request( - readItems("posts", { - filter: { status: { _eq: "published" } }, - sort: ["-date_created"], - fields: ["id", "title", "date_created"], - limit: 3, - }), + readItems('posts', { + filter: { status: { _eq: 'published' } }, + sort: ['-date_created'], + fields: ['id', 'title', 'date_created'], + limit: 3 + }) ); ``` ::callout{icon="i-lucide-info"} **Breakdown of snippet** - - Imports - `createDirectus` is required to create a client. - `rest` is required to make REST requests, and adds the `.request()` method. @@ -104,7 +94,7 @@ const somePosts = await directus.request( - Requests - `allPosts` makes a request to `readItems` in the `posts` collection. - `somePosts` does the same, but only the specified fields from the latest 3 published items. - :: +:: ::callout{icon="i-lucide-square-code" color="green" to="/api/items"} The API Reference contains SDK examples for endpoints, showing the required function usage. @@ -119,45 +109,33 @@ See all query parameters with SDK examples. To call custom endpoints using the SDK, you can manually provide a path and method. If using TypeScript, you can type the output. ::tabs -::div{class="pr-6"} - ---- - -label: JavaScript - ---- - -```js -import { createDirectus, rest } from "@directus/sdk"; -const directus = createDirectus("http://directus.example.com").with(rest()); - -const result = await directus.request(() => ({ - path: "/custom/endpoint", - method: "GET", -})); -``` - -:: -::div{class="pr-6"} - ---- - -label: TypeScript - ---- - -```ts -import { createDirectus, rest, customEndpoint } from "@directus/sdk"; -const directus = createDirectus("http://directus.example.com").with(rest()); - -const result = await directus.request( - customEndpoint({ - path: "/custom/endpoint", - method: "GET", - }), -); -``` - + ::div{class="pr-6"} + --- + label: JavaScript + --- + ```js + import { createDirectus, rest } from '@directus/sdk'; + const directus = createDirectus('http://directus.example.com').with(rest()); + + const result = await directus.request(() => ({ + path: '/custom/endpoint', + method: 'GET', + })); + ``` + :: + ::div{class="pr-6"} + --- + label: TypeScript + --- + ```ts + import { createDirectus, rest, customEndpoint } from '@directus/sdk'; + const directus = createDirectus('http://directus.example.com').with(rest()); + + const result = await directus.request(customEndpoint({ + path: '/custom/endpoint', + method: 'GET', + })); + ``` :: ### GraphQL Usage @@ -165,7 +143,7 @@ const result = await directus.request( Add the `graphql()` composable to the client, and use the `.query()` method. ```ts -import { createDirectus, graphql } from "@directus/sdk"; +import { createDirectus, graphql } from '@directus/sdk'; interface Post { id: number; @@ -177,9 +155,7 @@ interface Schema { posts: Post[]; } -const directus = createDirectus("http://directus.example.com").with( - graphql(), -); +const directus = createDirectus('http://directus.example.com').with(graphql()); const result = await directus.query(` query { @@ -197,10 +173,8 @@ const result = await directus.query(` The `authentication()` composable provides the Directus client with new `login()`, `logout()`, and `refresh()` methods. It also manages token storage and refreshing on your behalf. ```js -import { createDirectus, authentication } from "@directus/sdk"; -const directus = createDirectus("http://directus.example.com").with( - authentication(), -); +import { createDirectus, authentication } from '@directus/sdk'; +const directus = createDirectus('http://directus.example.com').with(authentication()); await directus.login({ email, password }, login_options); await directus.refresh(); @@ -226,10 +200,7 @@ type LoginOptions = { - `provider` specifies a non-redirect authentication provider. LDAP providers use `identifier` (typically a username) rather than `email`: ```js -await client.login( - { identifier: "username", password: "d1r3ctu5" }, - { provider: "ldap" }, -); +await client.login({ identifier: 'username', password: 'd1r3ctu5' }, { provider: 'ldap' }); ``` For SSO providers that use browser redirects (Google, GitHub, Okta, etc.), see [SSO Login](#sso-login) below. @@ -246,19 +217,17 @@ SSO providers like Google, GitHub, and Okta rely on browser redirects. The `.log Use `session` mode with `credentials: 'include'` so the session cookie set by Directus during the redirect is sent with subsequent requests. ```html - + Login with Google ``` ```js -import { createDirectus, authentication, rest, readMe } from "@directus/sdk"; +import { createDirectus, authentication, rest, readMe } from '@directus/sdk'; -const client = createDirectus("https://directus.example.com") - .with(authentication("session", { credentials: "include" })) - .with(rest({ credentials: "include" })); +const client = createDirectus('https://directus.example.com') + .with(authentication('session', { credentials: 'include' })) + .with(rest({ credentials: 'include' })); await client.refresh(); @@ -278,64 +247,49 @@ Read the Seamless SSO guide for session cookie configuration and local developme #### Set Token ::tabs -::div{class="pr-6"} - ---- - -label: Create client with token - ---- - -Import `staticToken` and use it when creating a client. - -```js -import { createDirectus, staticToken, rest } from "@directus/sdk"; -const directus = createDirectus("http://directus.example.com") - .with(staticToken("TOKEN")) - .with(rest()); -``` - -:: - -::div{class="pr-6"} - ---- - -label: Token for single requests - ---- - -Import `withToken` and use it as a request function with your token as the first parameter, and your original request as the second. - -```js -import { createDirectus, rest, withToken, readItems } from "@directus/sdk"; -const directus = createDirectus("http://directus.example.com").with(rest()); - -const request = await directus.request(withToken("TOKEN", readItems("posts"))); -``` - -:: - -::div{class="pr-6"} - ---- - -label: Set client token manually - ---- - -Import `authentication` or `staticToken` and use it when creating a client. You now have access to the `setToken` method. - -```js -import { createDirectus, authentication } from "@directus/sdk"; -const directus = createDirectus("http://directus.example.com").with( - authentication(), -); - -await directus.setToken("TOKEN"); -``` - -:: + ::div{class="pr-6"} + --- + label: Create client with token + --- + Import `staticToken` and use it when creating a client. + + ```js + import { createDirectus, staticToken, rest } from '@directus/sdk'; + const directus = createDirectus('http://directus.example.com') + .with(staticToken('TOKEN')) + .with(rest()); + ``` + :: + + ::div{class="pr-6"} + --- + label: Token for single requests + --- + Import `withToken` and use it as a request function with your token as the first parameter, and your original request as the second. + + ```js + import { createDirectus, rest, withToken, readItems } from '@directus/sdk'; + const directus = createDirectus('http://directus.example.com').with(rest()); + + const request = await directus.request( + withToken('TOKEN', readItems('posts')) + ); + ``` + :: + + ::div{class="pr-6"} + --- + label: Set client token manually + --- + Import `authentication` or `staticToken` and use it when creating a client. You now have access to the `setToken` method. + + ```js + import { createDirectus, authentication } from '@directus/sdk'; + const directus = createDirectus('http://directus.example.com').with(authentication()); + + await directus.setToken('TOKEN'); + ``` + :: :: #### Get a Token @@ -343,10 +297,8 @@ await directus.setToken("TOKEN"); Import `authentication` or `staticToken` and use it when creating a client. You now have access to the `getToken` method. ```js -import { createDirectus, authentication } from "@directus/sdk"; -const directus = createDirectus("http://directus.example.com").with( - authentication(), -); +import { createDirectus, authentication } from '@directus/sdk'; +const directus = createDirectus('http://directus.example.com').with(authentication()); const token = await directus.getToken(); ``` @@ -360,7 +312,7 @@ Internally, `getToken()` and `setToken()` make use of the configurable storage, Instead of storing `AuthData` in an object in the browser, this custom storage implementation stores and retrieves data in `localStorage`: ```js -import { createDirectus, authentication } from "@directus/sdk"; +import { createDirectus, authentication } from '@directus/sdk'; class LocalStorage { get() { @@ -372,21 +324,19 @@ class LocalStorage { } const storage = new LocalStorage(); -const directus = createDirectus("http://directus.example.com").with( - authentication("json", { storage }), -); +const directus = createDirectus('http://directus.example.com') + .with(authentication('json', { storage })); // Set a long term or static token without expiry information. -directus.setToken("TOKEN"); +directus.setToken('TOKEN'); // Set custom credentials to the storage. storage.set({ - access_token: "token", - refresh_token: "token", - expires_at: 123456789, + access_token: 'token', + refresh_token: 'token', + expires_at: 123456789 }); ``` - :: ### Cross-Domain Cookies @@ -394,17 +344,17 @@ storage.set({ A common situation is for the Directus backend and frontend to be hosted on different domains, requiring extra configuration to make sure cookies are passed correctly. Usually this is only required for authentication with cookies but this can be set globally for each composable that does requests. This will then apply to all requests made using that composable: ```js -const directus = createDirectus("http://directus.example.com") - .with(authentication("cookie", { credentials: "include" })) - .with(graphql({ credentials: "include" })) - .with(rest({ credentials: "include" })); +const directus = createDirectus('http://directus.example.com') + .with(authentication('cookie', { credentials: 'include' })) + .with(graphql({ credentials: 'include' })) + .with(rest({ credentials: 'include' })); ``` Or you can enable this only for specific REST requests using the `withOptions`: ```js const result = await directus.request( - withOptions(refresh(), { credentials: "include" }), + withOptions(refresh(), { credentials: 'include' }) ); ``` @@ -453,31 +403,31 @@ There are two polyfilling approaches, with the first taking precedence. #### Options Parameter of `createDirectus` ```js -import { createDirectus } from "@directus/sdk"; -import { ofetch } from "ofetch"; -import WebSocket from "ws"; +import { createDirectus } from '@directus/sdk'; +import { ofetch } from 'ofetch'; +import WebSocket from 'ws'; -const directus = createDirectus("http://directus.example.com", { +const directus = createDirectus('http://directus.example.com', { globals: { WebSocket: WebSocket, fetch: ofetch, - }, + } }); ``` #### `globalThis` object ```js -import { createDirectus } from "@directus/sdk"; -import { ofetch } from "ofetch"; -import WebSocket from "ws"; +import { createDirectus } from '@directus/sdk'; +import { ofetch } from 'ofetch'; +import WebSocket from 'ws'; globalThis.WebSocket = WebSocket; globalThis.fetch = ofetch; -import "react-native-url-polyfill/auto"; +import 'react-native-url-polyfill/auto'; -const directus = createDirectus("http://directus.example.com"); +const directus = createDirectus('http://directus.example.com'); ``` Polyfill libraries will often register itself to the `globalThis` object. For example, the `react-native-url-polyfill` package. From c880b1c884f3e72964a5327f827beee360894839 Mon Sep 17 00:00:00 2001 From: daedalus <44623501+ComfortablyCoding@users.noreply.github.com> Date: Fri, 5 Jun 2026 16:59:05 -0400 Subject: [PATCH 4/4] Fix tabs --- content/guides/04.connect/6.sdk.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/content/guides/04.connect/6.sdk.md b/content/guides/04.connect/6.sdk.md index 98b139561..969bcb8f4 100644 --- a/content/guides/04.connect/6.sdk.md +++ b/content/guides/04.connect/6.sdk.md @@ -22,8 +22,8 @@ The Directus SDK is a "Composable Client" that allows you to customize and build | `realtime()` | Adds `.connect()`, `.subscribe()`, `.sendMessage()`, and `.onWebSocket()` methods. Also adds reconnect logic. | | `staticToken()` | Adds `.setToken()` and `.getToken()` methods for manually managing tokens. | -::tabs - ::div{class="pr-6"} +::::tabs + :::div{class="pr-6"} --- label: JavaScript --- @@ -31,9 +31,9 @@ The Directus SDK is a "Composable Client" that allows you to customize and build import { createDirectus, rest } from '@directus/sdk'; const directus = createDirectus('http://directus.example.com').with(rest()); ``` - :: + ::: - ::div{class="pr-6"} + :::div{class="pr-6"} --- label: TypeScript --- @@ -54,11 +54,12 @@ The Directus SDK is a "Composable Client" that allows you to customize and build const directus = createDirectus('http://directus.example.com').with(rest()); ``` -:: -::callout{icon="i-lucide-graduation-cap" color="secondary" to="/tutorials/tips-and-tricks/advanced-types-with-the-directus-sdk"} - Learn how to leverage TypeScript with the SDK for auto-completion and generated output types. -:: + ::callout{icon="i-lucide-graduation-cap" color="secondary" to="/tutorials/tips-and-tricks/advanced-types-with-the-directus-sdk"} + Learn how to leverage TypeScript with the SDK for auto-completion and generated output types. + :: + ::: +:::: ## Making Requests @@ -136,6 +137,7 @@ To call custom endpoints using the SDK, you can manually provide a path and meth method: 'GET', })); ``` + :: :: ### GraphQL Usage