From 2dcc14e43ba133c8aa14106aae2abc54893ddb4d Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 13 Dec 2025 11:08:53 -0600 Subject: [PATCH 1/9] feat(dev-toolbar): add DevToolbarPlacement type Add exported type for toolbar placement options and extend DevToolbarMetadata to include optional placement property. --- packages/astro/src/types/public/toolbar.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/astro/src/types/public/toolbar.ts b/packages/astro/src/types/public/toolbar.ts index 21b1db6b72cd..fce192d3682b 100644 --- a/packages/astro/src/types/public/toolbar.ts +++ b/packages/astro/src/types/public/toolbar.ts @@ -61,6 +61,8 @@ export type DevToolbarApp = { // An app that has been loaded and as such contain all of its properties export type ResolvedDevToolbarApp = DevToolbarAppMeta & DevToolbarApp; +export type DevToolbarPlacement = 'bottom-left' | 'bottom-center' | 'bottom-right'; + export type DevToolbarMetadata = Window & typeof globalThis & { __astro_dev_toolbar__: { @@ -68,5 +70,6 @@ export type DevToolbarMetadata = Window & version: string; latestAstroVersion: string | undefined; debugInfo: string; + placement?: DevToolbarPlacement; }; }; From 6ce7ae2d6a68a380c4aecfc4286a0df990ab016d Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 13 Dec 2025 11:10:07 -0600 Subject: [PATCH 2/9] feat(dev-toolbar): add placement config option Add optional `placement` property to devToolbar config schema and interface with JSDoc documentation. --- packages/astro/src/core/config/schemas/base.ts | 1 + packages/astro/src/types/public/config.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/packages/astro/src/core/config/schemas/base.ts b/packages/astro/src/core/config/schemas/base.ts index c2b4a42ef992..485f3948ea4d 100644 --- a/packages/astro/src/core/config/schemas/base.ts +++ b/packages/astro/src/core/config/schemas/base.ts @@ -293,6 +293,7 @@ export const AstroConfigSchema = z.object({ devToolbar: z .object({ enabled: z.boolean().default(ASTRO_CONFIG_DEFAULTS.devToolbar.enabled), + placement: z.enum(['bottom-left', 'bottom-center', 'bottom-right']).optional(), }) .default(ASTRO_CONFIG_DEFAULTS.devToolbar), markdown: z diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts index 4961027c1f27..409b6444e142 100644 --- a/packages/astro/src/types/public/config.ts +++ b/packages/astro/src/types/public/config.ts @@ -1171,6 +1171,18 @@ export interface AstroUserConfig< * This option is scoped to the entire project, to only disable the toolbar for yourself, run `npm run astro preferences disable devToolbar`. To disable the toolbar for all your Astro projects, run `npm run astro preferences disable devToolbar --global`. */ enabled: boolean; + + /** + * @docs + * @name devToolbar.placement + * @type {'bottom-left' | 'bottom-center' | 'bottom-right'} + * @default `'bottom-center'` + * @description + * The default placement of the Astro Dev Toolbar on the screen. + * + * The user can still change the placement via the toolbar settings UI. Once changed, the user's preference is saved in `localStorage` and overrides this configuration value. + */ + placement?: 'bottom-left' | 'bottom-center' | 'bottom-right'; }; /** From c4f130ab67f181e975e6efb166fbdeefecb41ba6 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 13 Dec 2025 11:11:00 -0600 Subject: [PATCH 3/9] feat(dev-toolbar): pass placement config to client metadata Pass the devToolbar.placement config value to the client via __astro_dev_toolbar__ metadata injection. --- packages/astro/src/vite-plugin-astro-server/pipeline.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/astro/src/vite-plugin-astro-server/pipeline.ts b/packages/astro/src/vite-plugin-astro-server/pipeline.ts index 7d95a11b2d7c..50200d7146cd 100644 --- a/packages/astro/src/vite-plugin-astro-server/pipeline.ts +++ b/packages/astro/src/vite-plugin-astro-server/pipeline.ts @@ -101,6 +101,7 @@ export class DevPipeline extends Pipeline { // enabled, it would nice to request the debug info through import.meta.hot // when the button is click to defer execution as much as possible debugInfo: await this.getDebugInfo(), + placement: settings.config.devToolbar.placement, }; // Additional data for the dev overlay From 44b7149c9ab4180c34d165bf610a6b5cd35c2c1e Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 13 Dec 2025 11:11:52 -0600 Subject: [PATCH 4/9] feat(dev-toolbar): implement placement priority chain Implement the settings priority chain: 1. defaultSettings (hardcoded 'bottom-center') 2. Config placement (from astro.config.mjs) 3. localStorage (user's persisted choice) This allows project-level default placement while still respecting user's UI-driven placement preferences. --- .../astro/src/runtime/client/dev-toolbar/settings.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/runtime/client/dev-toolbar/settings.ts b/packages/astro/src/runtime/client/dev-toolbar/settings.ts index 1f4ce78e6e02..996e94d61129 100644 --- a/packages/astro/src/runtime/client/dev-toolbar/settings.ts +++ b/packages/astro/src/runtime/client/dev-toolbar/settings.ts @@ -1,4 +1,5 @@ -import type { Placement } from './ui-library/window.js'; +import type { DevToolbarMetadata } from '../../../types/public/toolbar.js'; +import { isValidPlacement, type Placement } from './ui-library/window.js'; export interface Settings { disableAppNotification: boolean; @@ -15,7 +16,16 @@ export const defaultSettings = { export const settings = getSettings(); function getSettings() { + // 1. Start with hardcoded defaults let _settings: Settings = { ...defaultSettings }; + + // 2. Override with config placement (if provided) + const configPlacement = (globalThis as DevToolbarMetadata).__astro_dev_toolbar__?.placement; + if (configPlacement && isValidPlacement(configPlacement)) { + _settings.placement = configPlacement; + } + + // 3. Override with localStorage (preserves user's UI choice) const toolbarSettings = localStorage.getItem('astro:dev-toolbar:settings'); if (toolbarSettings) { From 5b2a512a338067d46a036e89153cb25ae72f326a Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 13 Dec 2025 11:12:51 -0600 Subject: [PATCH 5/9] test(dev-toolbar): add config validation tests for placement Test that: - Valid placement values are accepted - Placement is optional (can be omitted) - Invalid placement values are rejected --- .../test/units/config/config-validate.test.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/astro/test/units/config/config-validate.test.js b/packages/astro/test/units/config/config-validate.test.js index 6dc9555cb281..b84e0a7c4dda 100644 --- a/packages/astro/test/units/config/config-validate.test.js +++ b/packages/astro/test/units/config/config-validate.test.js @@ -589,4 +589,29 @@ describe('Config Validation', () => { ); }); }); + + describe('devToolbar', () => { + it('should allow valid placement values', async () => { + for (const placement of ['bottom-left', 'bottom-center', 'bottom-right']) { + const result = await validateConfig({ + devToolbar: { placement }, + }); + assert.equal(result.devToolbar.placement, placement); + } + }); + + it('should allow omitting placement (optional)', async () => { + const result = await validateConfig({ + devToolbar: { enabled: true }, + }); + assert.equal(result.devToolbar.placement, undefined); + }); + + it('should reject invalid placement values', async () => { + const configError = await validateConfig({ + devToolbar: { placement: 'top-left' }, + }).catch((err) => err); + assert.equal(configError instanceof z.ZodError, true); + }); + }); }); From 27532c16a98cf855586522b6dd6902b8014b15a1 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 13 Dec 2025 11:13:37 -0600 Subject: [PATCH 6/9] chore: add changeset for devToolbar.placement config Minor version bump per Astro convention for new config options. --- .changeset/tidy-moles-brush.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tidy-moles-brush.md diff --git a/.changeset/tidy-moles-brush.md b/.changeset/tidy-moles-brush.md new file mode 100644 index 000000000000..537b45db63dc --- /dev/null +++ b/.changeset/tidy-moles-brush.md @@ -0,0 +1,5 @@ +--- +'astro': minor +--- + +Adds optional `placement` config option for the dev toolbar. Configure the default toolbar position (`'bottom-left'`, `'bottom-center'`, or `'bottom-right'`) via `devToolbar.placement` in your Astro config. User preferences from the toolbar UI (stored in localStorage) still take priority. From 74e5ac8fddd41fba591429283758fa72f321b8c0 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Tue, 13 Jan 2026 18:20:42 -0600 Subject: [PATCH 7/9] docs: Comment improvements Include @version added and tweak comment copy Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --- packages/astro/src/types/public/config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts index 409b6444e142..caeed6522661 100644 --- a/packages/astro/src/types/public/config.ts +++ b/packages/astro/src/types/public/config.ts @@ -1175,12 +1175,13 @@ export interface AstroUserConfig< /** * @docs * @name devToolbar.placement + * @version 5.17.0 * @type {'bottom-left' | 'bottom-center' | 'bottom-right'} * @default `'bottom-center'` * @description * The default placement of the Astro Dev Toolbar on the screen. * - * The user can still change the placement via the toolbar settings UI. Once changed, the user's preference is saved in `localStorage` and overrides this configuration value. + * The placement of the toolbar can still be changed via the toolbar settings UI. Once changed, the user's preference is saved in `localStorage` and overrides this configuration value. */ placement?: 'bottom-left' | 'bottom-center' | 'bottom-right'; }; From dbd595b34733bf56a4bf1350f3ca7965160aaa67 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Tue, 13 Jan 2026 18:33:54 -0600 Subject: [PATCH 8/9] docs: Update changeset Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --- .changeset/tidy-moles-brush.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.changeset/tidy-moles-brush.md b/.changeset/tidy-moles-brush.md index 537b45db63dc..fb6969d57a4b 100644 --- a/.changeset/tidy-moles-brush.md +++ b/.changeset/tidy-moles-brush.md @@ -2,4 +2,19 @@ 'astro': minor --- -Adds optional `placement` config option for the dev toolbar. Configure the default toolbar position (`'bottom-left'`, `'bottom-center'`, or `'bottom-right'`) via `devToolbar.placement` in your Astro config. User preferences from the toolbar UI (stored in localStorage) still take priority. +Adds optional `placement` config option for the dev toolbar. + +You can now configure the default toolbar position (`'bottom-left'`, `'bottom-center'`, or `'bottom-right'`) via `devToolbar.placement` in your Astro config. This option is helpful for sites with UI elements (chat widgets, cookie banners) that are consistently obscured by the toolbar in the dev environment. + +You can set a project default that is consistent across environments (e.g. dev machines, browser instances, team members): + +``` +//astro.config.mjs +export default defineConfig({ + devToolbar: { + placement: 'bottom-left', + }, +}); +``` + +User preferences from the toolbar UI (stored in `localStorage`) still take priority, so this setting can be overriden in individual situations as necessary. From f412cfd5bd119906a8e941b35bcf9f60f67b858a Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Tue, 13 Jan 2026 18:38:08 -0600 Subject: [PATCH 9/9] docs: Polish changeset formatting and fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add js syntax highlighting to code block - Fix spacing in comment - Fix "overriden" → "overridden" typo --- .changeset/tidy-moles-brush.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.changeset/tidy-moles-brush.md b/.changeset/tidy-moles-brush.md index fb6969d57a4b..46163cef68b4 100644 --- a/.changeset/tidy-moles-brush.md +++ b/.changeset/tidy-moles-brush.md @@ -8,8 +8,8 @@ You can now configure the default toolbar position (`'bottom-left'`, `'bottom-ce You can set a project default that is consistent across environments (e.g. dev machines, browser instances, team members): -``` -//astro.config.mjs +```js +// astro.config.mjs export default defineConfig({ devToolbar: { placement: 'bottom-left', @@ -17,4 +17,4 @@ export default defineConfig({ }); ``` -User preferences from the toolbar UI (stored in `localStorage`) still take priority, so this setting can be overriden in individual situations as necessary. +User preferences from the toolbar UI (stored in `localStorage`) still take priority, so this setting can be overridden in individual situations as necessary.