Fullscreen API

Fullscreen views give plugins a dedicated, full-height page within the Ghosty application. They are ideal for content-rich experiences like task managers, dashboards, settings panels, or any interface that needs more space than a widget can provide.

Declaring a fullscreen view

Add a fullscreen block to the views section of your plugin.yaml:

views:
  fullscreen:
    entry: src/fullscreen.ts
    title: My Plugin
    show_back_button: true
    settings_entry: src/settings.ts
FieldTypeDefaultDescription
entrystring(required)Path to the fullscreen entry file.
titlestringdisplay_nameTitle shown in the Ghosty navigation bar.
show_back_buttonbooleantrueWhether to show the back arrow in the nav bar.
settings_entrystringnullOptional path to a settings panel entry file.

Entry file

Your fullscreen entry file must export a render function that receives the container element:

export function render(container: HTMLElement): void {
  container.innerHTML = `
    <div class="fullscreen-app">
      <header class="toolbar">
        <h1>My Plugin</h1>
      </header>
      <main class="content">
        <p>Full-screen content goes here.</p>
      </main>
    </div>
  `;
}

The container element spans the full width and height of the Ghosty content area (below the navigation bar). Unlike the widget container, there are no fixed size constraints.

Navigation bar

The Ghosty navigation bar appears at the top of fullscreen views and includes:

  • Back button (optional) -- returns to the previous screen.
  • Title -- the title from your manifest.
  • Settings gear (optional) -- opens your plugin's settings panel.

Controlling the title at runtime

You can update the navigation bar title dynamically:

POSTghosty.fullscreen.setTitle(title)

Update the title displayed in the navigation bar.

Parameters

NameTypeRequiredDescription
titlestringYesThe new title. Max 60 characters.
import { ghosty } from "@ghosty/sdk";
 
// Change the title based on current context
ghosty.fullscreen.setTitle("Project: Acme Corp");

Back button handling

When the user taps the back button, the default behaviour is to return to the dashboard. You can intercept this to show a confirmation dialog or save state before navigating away.

POSTghosty.fullscreen.onBackPress(callback)

Register a callback that fires when the user presses the back button. Return false to prevent default navigation.

Parameters

NameTypeRequiredDescription
callback() => booleanYesReturn false to prevent the back navigation, true to allow it.

Example: unsaved changes warning

import { ghosty } from "@ghosty/sdk";
 
let hasUnsavedChanges = false;
 
ghosty.fullscreen.onBackPress(() => {
  if (hasUnsavedChanges) {
    const confirmed = confirm("You have unsaved changes. Discard them?");
    if (!confirmed) {
      return false; // Prevent navigation
    }
  }
  return true; // Allow navigation
});
 
// Mark as dirty when the user edits something
document.getElementById("editor")?.addEventListener("input", () => {
  hasUnsavedChanges = true;
});
Do not trap the user

Always provide a way for the user to leave the fullscreen view. Plugins that permanently block back navigation will be rejected during review.

Settings panel

If you declare a settings_entry in the manifest, a gear icon appears in the navigation bar. When the user taps it, Ghosty opens a slide-over panel and renders your settings view inside it.

Settings entry file

export function render(container: HTMLElement): void {
  container.innerHTML = `
    <div class="settings-panel">
      <h2>Settings</h2>
 
      <label>
        <span>City</span>
        <input type="text" id="city-input" placeholder="London" />
      </label>
 
      <button id="save-btn" type="button">Save</button>
    </div>
  `;
 
  // Wire up save logic
  document.getElementById("save-btn")?.addEventListener("click", async () => {
    const city = (document.getElementById("city-input") as HTMLInputElement)?.value;
    await ghosty.storage.set("city", city);
    ghosty.notifications.toast("Settings saved!", { variant: "success" });
  });
}

Settings lifecycle

The settings panel has its own simplified lifecycle:

EventWhen
render calledThe panel is opened for the first time.
Panel closedThe panel slides away. No explicit hook fires.
Panel re-openedrender is called again (a fresh container).
Settings persistence

Use ghosty.storage to persist settings values. Load saved values in render and populate the form fields so the user sees their current configuration.

Fullscreen navigation stack

Fullscreen plugins can implement their own internal navigation by swapping content within the container. The Ghosty host does not manage sub-routes for you; you are responsible for rendering different views based on your own application state.

Pattern: simple router

import { ghosty } from "@ghosty/sdk";
 
type Route = "list" | "detail" | "create";
let currentRoute: Route = "list";
 
const routes: Record<Route, (container: HTMLElement) => void> = {
  list: renderListView,
  detail: renderDetailView,
  create: renderCreateView,
};
 
function navigateTo(container: HTMLElement, route: Route): void {
  currentRoute = route;
  routes[route](container);
 
  // Update the nav bar title to reflect the current view
  const titles: Record<Route, string> = {
    list: "My Tasks",
    detail: "Task Details",
    create: "New Task",
  };
  ghosty.fullscreen.setTitle(titles[route]);
}
 
export function render(container: HTMLElement): void {
  navigateTo(container, "list");
 
  // Handle back button for internal navigation
  ghosty.fullscreen.onBackPress(() => {
    if (currentRoute !== "list") {
      navigateTo(container, "list");
      return false; // Handled internally
    }
    return true; // Let Ghosty navigate back to the dashboard
  });
}

Keyboard shortcuts

Fullscreen views can register keyboard shortcuts that are active only when the plugin is in focus:

POSTghosty.fullscreen.registerShortcut(key, callback)

Register a keyboard shortcut active during fullscreen mode.

Parameters

NameTypeRequiredDescription
keystringYesKey combination (e.g. 'Ctrl+S', 'Cmd+Enter', 'Escape').
callback(event: KeyboardEvent) => voidYesHandler function.
import { ghosty } from "@ghosty/sdk";
 
ghosty.fullscreen.registerShortcut("Ctrl+S", (event) => {
  event.preventDefault();
  saveCurrentDocument();
});
 
ghosty.fullscreen.registerShortcut("Ctrl+N", (event) => {
  event.preventDefault();
  createNewItem();
});
Platform-aware shortcuts

Use Ctrl in your shortcut strings. The runtime automatically translates Ctrl to Cmd on macOS and Ctrl on Windows and Linux.

Scrolling

The fullscreen container uses overflow-y: auto by default, so content taller than the viewport scrolls naturally. If you want to implement custom scrolling (e.g. virtual scrolling for long lists), set overflow: hidden on the container and manage scrolling yourself.

Best practices

  1. Show a loading state immediately. Fullscreen views can display large amounts of data. Render a skeleton UI on first paint and populate asynchronously.
  2. Implement internal back navigation. If your plugin has multiple screens, use onBackPress to navigate internally before falling through to the host.
  3. Keep settings lightweight. The settings panel is small. Avoid complex multi-step wizards; use the fullscreen view for those.
  4. Test keyboard shortcuts. Make sure shortcuts do not conflict with Ghosty host shortcuts (e.g. Ctrl+Q for quit).
  5. Handle orientation changes. On mobile, the fullscreen view may rotate. Use responsive CSS to adapt.
  6. Provide a way back. Even if show_back_button is true, include visible navigation affordances within your UI so the user is never stuck.