--- title: dialogs Overview description: Display native system dialogs in your application sidebar: order: 1 --- import { Tabs, TabItem, Card, CardGrid } from "@astrojs/starlight/components"; ## Native dialogs Wails provides **native system dialogs** that work across all platforms: message dialogs (info, warning, error, question), file dialogs (open, save, folder), and custom dialog windows with platform-native appearance and behaviour. ## Quick Start ```go // Information dialog app.Dialog.Info(). SetTitle("Success"). SetMessage("File saved successfully!"). Show() // Question dialog with button callbacks dialog := app.Dialog.Question(). SetTitle("Confirm"). SetMessage("Delete this file?") deleteBtn := dialog.AddButton("Delete") deleteBtn.OnClick(func() { deleteFile() }) cancelBtn := dialog.AddButton("Cancel") dialog.SetDefaultButton(cancelBtn) dialog.SetCancelButton(cancelBtn) dialog.Show() // File open dialog path, _ := app.Dialog.OpenFile(). SetTitle("Select Image"). AddFilter("Images", "*.png;*.jpg"). PromptForSingleSelection() ``` **That's it!** Native dialogs with minimal code. ## Accessing Dialogs Dialogs are accessed through the `app.Dialog` manager: ```go app.Dialog.Info() app.Dialog.Question() app.Dialog.Warning() app.Dialog.Error() app.Dialog.OpenFile() app.Dialog.SaveFile() ``` ## dialog Types ### Information dialog Display simple messages: ```go app.Dialog.Info(). SetTitle("Welcome"). SetMessage("Welcome to our application!"). Show() ``` **Use cases:** - Success messages - Informational notices - Completion confirmations ### Warning dialog Show warnings: ```go app.Dialog.Warning(). SetTitle("Warning"). SetMessage("This action cannot be undone."). Show() ``` **Use cases:** - Non-critical warnings - Deprecation notices - Caution messages ### Error dialog Display errors: ```go app.Dialog.Error(). SetTitle("Error"). SetMessage("Failed to save file: " + err.Error()). Show() ``` **Use cases:** - Error messages - Failure notifications - Exception handling ### Question dialog Ask users questions and handle responses via button callbacks: ```go dialog := app.Dialog.Question(). SetTitle("Confirm Delete"). SetMessage("Are you sure you want to delete this file?") deleteBtn := dialog.AddButton("Delete") deleteBtn.OnClick(func() { deleteFile() }) cancelBtn := dialog.AddButton("Cancel") dialog.SetDefaultButton(cancelBtn) dialog.SetCancelButton(cancelBtn) dialog.Show() ``` **Use cases:** - Confirm actions - Yes/No questions - Multiple choice ## File dialogs ### Open File dialog Select files to open: ```go path, err := app.Dialog.OpenFile(). SetTitle("Select Image"). AddFilter("Images", "*.png;*.jpg;*.gif"). AddFilter("All Files", "*.*"). PromptForSingleSelection() if err == nil && path != "" { openFile(path) } ``` **Multiple selection:** ```go paths, err := app.Dialog.OpenFile(). SetTitle("Select Images"). AddFilter("Images", "*.png;*.jpg"). PromptForMultipleSelection() if err == nil { for _, path := range paths { processFile(path) } } ``` ### Save File dialog Choose where to save: ```go path, err := app.Dialog.SaveFile(). SetFilename("document.txt"). AddFilter("Text Files", "*.txt"). AddFilter("All Files", "*.*"). PromptForSingleSelection() if err == nil && path != "" { saveFile(path) } ``` ### Select Folder dialog Choose a directory using the open file dialog with directory selection enabled: ```go path, err := app.Dialog.OpenFile(). SetTitle("Select Output Folder"). CanChooseDirectories(true). CanChooseFiles(false). PromptForSingleSelection() if err == nil && path != "" { exportToFolder(path) } ``` ## dialog Options ### Title and Message ```go dialog := app.Dialog.Info(). SetTitle("Success"). SetMessage("Operation completed successfully!") ``` ### Buttons **Default button for simple dialogs:** Info, warning, and error dialogs display a default "OK" button: ```go app.Dialog.Info(). SetMessage("Done!"). Show() ``` **Custom buttons for question dialogs:** Use `AddButton()` to add buttons, which returns a `*Button` you can configure with callbacks: ```go dialog := app.Dialog.Question(). SetMessage("Choose action") save := dialog.AddButton("Save") save.OnClick(func() { saveDocument() }) dontSave := dialog.AddButton("Don't Save") dontSave.OnClick(func() { discardChanges() }) cancel := dialog.AddButton("Cancel") // No callback needed - just dismisses dialog dialog.SetDefaultButton(save) dialog.SetCancelButton(cancel) dialog.Show() ``` **Default and Cancel buttons:** Use `SetDefaultButton()` to specify which button is highlighted and triggered by Enter. Use `SetCancelButton()` to specify which button is triggered by Escape. ```go dialog := app.Dialog.Question(). SetMessage("Delete file?") deleteBtn := dialog.AddButton("Delete") deleteBtn.OnClick(func() { performDelete() }) cancelBtn := dialog.AddButton("Cancel") dialog.SetDefaultButton(cancelBtn) // Safe option highlighted by default dialog.SetCancelButton(cancelBtn) // Escape triggers Cancel dialog.Show() ``` ### Window Attachment Attach dialog to specific window: ```go dialog := app.Dialog.Info(). SetMessage("Window-specific message"). AttachToWindow(window) dialog.Show() ``` **Behaviour:** - dialog appears centred on parent window - Parent window disabled whilst dialog shown - dialog moves with parent window (macOS) ## Platform Behaviour **macOS dialogs:** - Native NSAlert appearance - Follow system theme (light/dark) - Support keyboard navigation - Standard shortcuts (⌘. for Cancel) - Accessibility features built-in - Sheet-style when attached to window **Example:** ```go // Appears as sheet on macOS dialog := app.Dialog.Question(). SetMessage("Save changes?"). AttachToWindow(window) dialog.AddButton("Yes") dialog.AddButton("No") dialog.Show() ``` **Windows dialogs:** - Native TaskDialog appearance - Follow system theme - Support keyboard navigation - Standard shortcuts (Esc for Cancel) - Accessibility features built-in - Modal to parent window **Example:** ```go // Modal dialog on Windows app.Dialog.Error(). SetTitle("Error"). SetMessage("Operation failed"). Show() ``` **Linux dialogs:** - GTK dialog appearance - Follow desktop theme - Support keyboard navigation - Desktop environment integration - Varies by DE (GNOME, KDE, etc.) **Example:** ```go // GTK dialog on Linux app.Dialog.Info(). SetMessage("Update complete"). Show() ``` ## Common Patterns ### Confirm Before Destructive Action ```go func deleteFile(app *application.App, path string) { dialog := app.Dialog.Question(). SetTitle("Confirm Delete"). SetMessage(fmt.Sprintf("Delete %s?", filepath.Base(path))) deleteBtn := dialog.AddButton("Delete") deleteBtn.OnClick(func() { if err := os.Remove(path); err != nil { app.Dialog.Error(). SetTitle("Delete Failed"). SetMessage(err.Error()). Show() } }) cancelBtn := dialog.AddButton("Cancel") dialog.SetDefaultButton(cancelBtn) dialog.SetCancelButton(cancelBtn) dialog.Show() } ``` ### Error Handling with dialog ```go func saveDocument(app *application.App, path string, data []byte) { if err := os.WriteFile(path, data, 0644); err != nil { app.Dialog.Error(). SetTitle("Save Failed"). SetMessage(fmt.Sprintf("Could not save file: %v", err)). Show() return } app.Dialog.Info(). SetTitle("Success"). SetMessage("File saved successfully!"). Show() } ``` ### File Selection with Validation ```go func selectImageFile(app *application.App) (string, error) { path, err := app.Dialog.OpenFile(). SetTitle("Select Image"). AddFilter("Images", "*.png;*.jpg;*.jpeg;*.gif"). PromptForSingleSelection() if err != nil { return "", err } if path == "" { return "", errors.New("no file selected") } // Validate file if !isValidImage(path) { app.Dialog.Error(). SetTitle("Invalid File"). SetMessage("Selected file is not a valid image."). Show() return "", errors.New("invalid image") } return path, nil } ``` ### Multi-Step dialog Flow ```go func exportData(app *application.App) { // Step 1: Confirm export dialog := app.Dialog.Question(). SetTitle("Export Data"). SetMessage("Export all data to CSV?") exportBtn := dialog.AddButton("Export") exportBtn.OnClick(func() { // Step 2: Select destination path, err := app.Dialog.SaveFile(). SetFilename("export.csv"). AddFilter("CSV Files", "*.csv"). PromptForSingleSelection() if err != nil || path == "" { return } // Step 3: Perform export if err := performExport(path); err != nil { app.Dialog.Error(). SetTitle("Export Failed"). SetMessage(err.Error()). Show() return } // Step 4: Success app.Dialog.Info(). SetTitle("Export Complete"). SetMessage("Data exported successfully!"). Show() }) cancelBtn := dialog.AddButton("Cancel") dialog.SetCancelButton(cancelBtn) dialog.Show() } ``` ## Best Practices ### ✅ Do - **Use native dialogs** - Better UX than custom - **Provide clear messages** - Be specific - **Set appropriate titles** - Context matters - **Use default buttons wisely** - Safe option as default - **Handle cancellation** - User might cancel - **Validate file selections** - Check file types ### ❌ Don't - **Don't overuse dialogs** - Interrupts workflow - **Don't use for frequent messages** - Use notifications - **Don't forget error handling** - User might cancel - **Don't block unnecessarily** - Consider alternatives - **Don't use generic messages** - Be specific - **Don't ignore platform differences** - Test on all platforms ## Next Steps Info, warning, and error dialogs. [Learn More →](/features/dialogs/message) Open, save, and folder selection. [Learn More →](/features/dialogs/file) Create custom dialog windows. [Learn More →](/features/dialogs/custom) Learn about window management. [Learn More →](/features/windows/basics) --- **Questions?** Ask in [Discord](https://discord.gg/JDdSxwjhGf) or check the [dialog examples](https://github.com/wailsapp/wails/tree/v3-alpha/v3/examples/dialogs).