### Setup Documentation Environment
Source: https://v3.wails.io/contributing/getting-started
Install dependencies and start the local development server for previewing documentation changes.
```bash
cd docs
npm install
npm run dev
```
--------------------------------
### Complete Browser Integration Example
Source: https://v3.wails.io/features/browser/integration
A comprehensive example demonstrating various browser integration patterns, including menu setup, dialogs for confirmation, and generating/opening HTML reports.
```go
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/wailsapp/wails/v3/pkg/application"
)
func main() {
app := application.New(application.Options{
Name: "Browser Integration Demo",
})
// Setup menu with browser actions
setupMenu(app)
// Create main window
window := app.Window.New()
window.SetTitle("Browser Integration")
err := app.Run()
if err != nil {
panic(err)
}
}
func setupMenu(app *application.App) {
menu := app.Menu.New()
// File menu
fileMenu := menu.AddSubmenu("File")
fileMenu.Add("Generate Report").OnClick(func(ctx *application.Context) {
generateHTMLReport(app)
})
// Help menu
helpMenu := menu.AddSubmenu("Help")
helpMenu.Add("Documentation").OnClick(func(ctx *application.Context) {
openWithConfirmation(app, "https://docs.example.com")
})
helpMenu.Add("Support").OnClick(func(ctx *application.Context) {
openWithConfirmation(app, "https://support.example.com")
})
app.Menu.Set(menu)
}
func openWithConfirmation(app *application.App, url string) {
dialog := app.Dialog.Question()
dialog.SetTitle("Open External Link")
dialog.SetMessage(fmt.Sprintf("Open %s in your browser?", url))
dialog.AddButton("Open").OnClick(func() {
if err := app.Browser.OpenURL(url); err != nil {
showError(app, "Failed to open URL", err)
}
})
dialog.AddButton("Cancel")
dialog.Show()
}
func generateHTMLReport(app *application.App) {
// Create temporary HTML file
tmpDir := os.TempDir()
reportPath := filepath.Join(tmpDir, "demo_report.html")
html := `
Report Details
This report was generated to demonstrate browser integration.
`
err := os.WriteFile(reportPath, []byte(html), 0644)
if err != nil {
showError(app, "Failed to create report", err)
return
}
// Open in browser
err = app.Browser.OpenFile(reportPath)
if err != nil {
showError(app, "Failed to open report", err)
}
}
func showError(app *application.App, message string, err error) {
app.Dialog.Error().
SetTitle("Error").
SetMessage(fmt.Sprintf("%s: %v", message, err)).
Show()
}
```
--------------------------------
### Quick Start: Create Platform-Native Menus
Source: https://v3.wails.io/features/menus/application
This snippet demonstrates the basic setup for creating application-wide menus that adapt to the native platform. It includes standard roles like File, Edit, and Help.
```go
package main
import (
"runtime"
"github.com/wailsapp/wails/v3/pkg/application"
)
func main() {
app := application.New(application.Options{
Name: "My App",
})
// Create menu
menu := app.NewMenu()
// Add standard menus (platform-appropriate)
if runtime.GOOS == "darwin" {
menu.AddRole(application.AppMenu) // macOS only
}
menu.AddRole(application.FileMenu)
menu.AddRole(application.EditMenu)
menu.AddRole(application.WindowMenu)
menu.AddRole(application.HelpMenu)
// Set the application menu
app.Menu.Set(menu)
// Create window with UseApplicationMenu to inherit the menu on Windows/Linux
app.Window.NewWithOptions(application.WebviewWindowOptions{
UseApplicationMenu: true,
})
app.Run()
}
```
--------------------------------
### NSIS Installer Script Example
Source: https://v3.wails.io/guides/installers
A sample NSIS script defining application name, version, output file, installation directory, and creating a desktop shortcut.
```nsis
!define APPNAME "MyApp"
!define VERSION "1.0.0"
Name "${APPNAME}"
OutFile "MyApp-Setup.exe"
InstallDir "$PROGRAMFILES\${APPNAME}"
Section "Install"
SetOutPath "$INSTDIR"
File "build\bin\myapp.exe"
CreateShortcut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\myapp.exe"
SectionEnd
```
--------------------------------
### Complete Application Setup with Browser Flags
Source: https://v3.wails.io/features/windows/options
A complete example demonstrating how to initialize a Wails application with custom Windows options, including enabling draggable regions and remote debugging, and then creating and running the main window.
```go
package main
import (
"github.com/wailsapp/wails/v3/pkg/application"
)
func main() {
app := application.New(application.Options{
Name: "My App",
Windows: application.WindowsOptions{
// Enable draggable regions feature
EnabledFeatures: []string{
"msWebView2EnableDraggableRegions",
},
// Enable remote debugging
AdditionalBrowserArgs: []string{
"--remote-debugging-port=9222",
},
},
})
// All windows will use the browser flags configured above
window := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Main Window",
Width: 1024,
Height: 768,
})
window.Show()
app.Run()
}
```
--------------------------------
### Run Wails Setup Wizard
Source: https://v3.wails.io/
Initialize a new Wails project using the setup wizard. This command is experimental and may require manual installation if issues arise.
```bash
wails3 setup
```
--------------------------------
### Quick Start: Create System Tray App
Source: https://v3.wails.io/features/menus/systray
A basic example demonstrating how to create a system tray icon with a label and a menu. The menu includes options to show the main window and quit the application. The main window is initially hidden.
```go
package main
import (
_ "embed"
"github.com/wailsapp/wails/v3/pkg/application"
)
//go:embed assets/icon.png
var icon []byte
func main() {
app := application.New(application.Options{
Name: "Tray App",
})
// Create system tray
systray := app.SystemTray.New()
systray.SetIcon(icon)
systray.SetLabel("My App")
// Add menu
menu := app.NewMenu()
menu.Add("Show").OnClick(func(ctx *application.Context) {
// Show main window
})
menu.Add("Quit").OnClick(func(ctx *application.Context) {
app.Quit()
})
systray.SetMenu(menu)
// Create hidden window
window := app.Window.New()
window.Hide()
app.Run()
}
```
--------------------------------
### Go: Handle Application Started Event
Source: https://v3.wails.io/features/events/system
Listen for the 'ApplicationStarted' system event in Go. This is useful for performing setup tasks when the application first launches.
```go
// Application lifecycle
app.Event.OnApplicationEvent(events.Common.ApplicationStarted, func(e *application.ApplicationEvent) {
app.Logger.Info("Application started")
})
```
--------------------------------
### Complete Window Example
Source: https://v3.wails.io/reference/window
A comprehensive example demonstrating window creation with various options, behavior configuration, event hooks, and application lifecycle management.
```go
package main
import (
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
)
func main() {
app := application.New(application.Options{
Name: "Window API Demo",
})
// Create window with options
window := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "My Application",
Width: 1024,
Height: 768,
MinWidth: 800,
MinHeight: 600,
BackgroundColour: application.NewRGB(255, 255, 255),
URL: "http://wails.localhost/",
})
// Configure window behaviour
window.SetResizable(true)
window.SetMinSize(800, 600)
window.SetMaxSize(1920, 1080)
// Confirm-before-close hook
window.RegisterHook(events.Common.WindowClosing, func(e *application.WindowEvent) {
dlg := app.Dialog.Question().
SetTitle("Confirm Close").
SetMessage("Are you sure you want to close this window?")
yes := dlg.AddButton("Yes")
no := dlg.AddButton("No")
dlg.SetDefaultButton(yes)
dlg.SetCancelButton(no)
no.OnClick(func() { e.Cancel() })
dlg.Show()
})
// Listen for window events
window.OnWindowEvent(events.Common.WindowFocus, func(e *application.WindowEvent) {
window.SetTitle("My Application (Active)")
app.Logger.Info("Window gained focus")
})
window.OnWindowEvent(events.Common.WindowLostFocus, func(e *application.WindowEvent) {
window.SetTitle("My Application")
app.Logger.Info("Window lost focus")
})
// Position and show window
window.Center()
window.Show()
app.Run()
}
```
--------------------------------
### Build Configuration Example (build/config.yml)
Source: https://v3.wails.io/concepts/build-system
Illustrative content for build/config.yml, which holds project metadata used for generating build assets like icons and installers.
```yaml
# build/config.yml (illustrative)
info:
productName: "My App"
productIdentifier: "com.example.myapp"
productVersion: "1.0.0"
companyName: "Example Ltd."
productDescription: "An application built with Wails"
```
--------------------------------
### Verify Wails Setup and Test App Creation
Source: https://v3.wails.io/contributing/setup
Runs a series of commands to verify the Go installation, build the Wails CLI, run unit tests, and create and run a new test application to confirm the environment is fully functional.
```bash
# Go version check
go version
# Build Wails
cd v3
go build ./cmd/wails3
# Run tests
go test ./pkg...
# Create a test app
cd ..
./wails3 init -n mytest -t vanilla
cd mytest
../wails3 dev
```
--------------------------------
### Complete Application Example
Source: https://v3.wails.io/reference/application
A full Go application example demonstrating Wails v3 initialization, window creation, and running the application.
```go
package main
import (
"github.com/wailsapp/wails/v3/pkg/application"
)
func main() {
app := application.New(application.Options{
Name: "My Application",
Description: "A demo application",
Mac: application.MacOptions{
ApplicationShouldTerminateAfterLastWindowClosed: true,
},
})
// Create main window
window := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "My App",
Width: 1024,
Height: 768,
MinWidth: 800,
MinHeight: 600,
BackgroundColour: application.NewRGB(255, 255, 255),
URL: "http://wails.localhost/",
})
window.Center()
window.Show()
app.Run()
}
```
--------------------------------
### Install Frontend Dependencies
Source: https://v3.wails.io/guides/advanced/custom-templates
Once the frontend project is initialized, run `npm install` in the `frontend/` directory to install all necessary dependencies for your frontend build.
```bash
npm install
```
--------------------------------
### Run Wails Server Example
Source: https://v3.wails.io/guides/server-build
Demonstrates how to navigate to the server example directory and run the Wails server application using Taskfile or directly with Go.
```bash
cd v3/examples/server
```
```bash
# Using Taskfile
task dev
```
```bash
# Or run directly
go run -tags server .
```
```bash
# Open http://localhost:8080 in browser
```
--------------------------------
### Accelerator Examples
Source: https://v3.wails.io/features/menus/reference
Examples of common accelerator key combinations for menu items, including platform-specific conventions.
```go
"CmdOrCtrl+S" // Save
"CmdOrCtrl+Shift+S" // Save As
"CmdOrCtrl+W" // Close Window
"CmdOrCtrl+Q" // Quit
"F5" // Refresh
"CmdOrCtrl+," // Preferences (macOS convention)
"Alt+F4" // Close (Windows convention)
```
--------------------------------
### Install NSIS and Create Installer Script
Source: https://v3.wails.io/guides/installers
This snippet shows how to install NSIS and create a basic installer script for a Windows application.
```bash
# Install NSIS
# Download from: https://nsis.sourceforge.io/
# Create installer script (installer.nsi)
makensis installer.nsi
```
--------------------------------
### Install Go using Tarball (Linux)
Source: https://v3.wails.io/quick-start/installation
Installs Go on Linux by extracting a tarball. Requires manual removal of previous installations.
```bash
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.25.linux-amd64.tar.gz
```
--------------------------------
### Complete UserService Example
Source: https://v3.wails.io/features/bindings/services
A comprehensive example of a Wails v3 service demonstrating database integration (SQLite), caching, and lifecycle management (startup/shutdown).
```go
package main
import (
"context"
"database/sql"
"fmt"
"log/slog"
"sync"
"time"
"github.com/wailsapp/wails/v3/pkg/application"
_ "github.com/mattn/go-sqlite3"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
CreatedAt time.Time `json:"createdAt"`
}
type UserService struct {
db *sql.DB
logger *slog.Logger
cache map[int]*User
mu sync.RWMutex
}
func NewUserService(logger *slog.Logger) *UserService {
return &UserService{
logger: logger,
cache: make(map[int]*User),
}
}
func (u *UserService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
u.logger.Info("Starting UserService")
// Open database
db, err := sql.Open("sqlite3", "users.db")
if err != nil {
return fmt.Errorf("failed to open database: %w", err)
}
u.db = db
// Create table
_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`)
if err != nil {
return fmt.Errorf("failed to create table: %w", err)
}
// Preload cache
if err := u.loadCache(); err != nil {
return fmt.Errorf("failed to load cache: %w", err)
}
return nil
}
func (u *UserService) ServiceShutdown() error {
u.logger.Info("Shutting down UserService")
if u.db != nil {
return u.db.Close()
}
return nil
}
func (u *UserService) GetUser(id int) (*User, error) {
// Check cache first
u.mu.RLock()
if user, ok := u.cache[id]; ok {
u.mu.RUnlock()
return user, nil
}
u.mu.RUnlock()
// Query database
var user User
err := u.db.QueryRow(
"SELECT id, name, email, created_at FROM users WHERE id = ?",
id,
).Scan(&user.ID, &user.Name, &user.Email, &user.CreatedAt)
if err == sql.ErrNoRows {
return nil, fmt.Errorf("user %d not found", id)
}
if err != nil {
return nil, fmt.Errorf("database error: %w", err)
}
// Update cache
u.mu.Lock()
u.cache[id] = &user
u.mu.Unlock()
return &user, nil
}
func (u *UserService) CreateUser(name, email string) (*User, error) {
result, err := u.db.Exec(
"INSERT INTO users (name, email) VALUES (?, ?)",
name, email,
)
if err != nil {
return nil, fmt.Errorf("failed to create user: %w", err)
}
id, _ := result.LastInsertId()
user := &User{
ID: int(id),
Name: name,
Email: email,
CreatedAt: time.Now(),
}
// Update cache
u.mu.Lock()
u.cache[int(id)] = user
u.mu.Unlock()
u.logger.Info("User created", "id", id, "email", email)
return user, nil
}
func (u *UserService) loadCache() error {
rows, err := u.db.Query("SELECT id, name, email, created_at FROM users")
if err != nil {
return err
}
defer rows.Close()
u.mu.Lock()
defer u.mu.Unlock()
for rows.Next() {
var user User
if err := rows.Scan(&user.ID, &user.Name, &user.Email, &user.CreatedAt); err != nil {
return err
}
u.cache[user.ID] = &user
}
return rows.Err()
}
func main() {
app := application.New(application.Options{
Name: "User Management",
Services: []application.Service{
application.NewService(NewUserService(slog.Default())),
},
})
app.Window.New()
app.Run()
}
```
--------------------------------
### Listen to Windows Application Start Event
Source: https://v3.wails.io/concepts/lifecycle
Handle the specific application start event on Windows.
```go
// Windows
app.Event.OnApplicationEvent(events.Windows.ApplicationStarted, func(event *application.ApplicationEvent) {
// Handle Windows start
})
```
--------------------------------
### Listen to Application Start Event
Source: https://v3.wails.io/concepts/lifecycle
Subscribe to the common application start event to execute code when the application begins.
```go
app.Event.OnApplicationEvent(events.Common.ApplicationStarted, func(event *application.ApplicationEvent) {
app.Logger.Info("Application has started!")
})
```
--------------------------------
### Install Go using Package Manager (Linux)
Source: https://v3.wails.io/quick-start/installation
Installs Go on various Linux distributions using their respective package managers.
```bash
# Ubuntu/Debian
sudo apt install golang-go
# Fedora
sudo dnf install golang
# Arch
sudo pacman -S go
```
--------------------------------
### Install Go using Homebrew (macOS)
Source: https://v3.wails.io/quick-start/installation
Installs Go on macOS using the Homebrew package manager.
```bash
brew install go
```
--------------------------------
### Install Project Dependencies
Source: https://v3.wails.io/concepts/build-system
Ensure all necessary project dependencies are installed for both the frontend (npm) and backend (Go modules) by running their respective download commands.
```bash
# Install dependencies
npm install
go mod download
```
--------------------------------
### Install Missing WebKit Dependencies
Source: https://v3.wails.io/guides/build/linux
Install the runtime WebKitGTK dependencies if your application fails to start on Linux.
```bash
# Debian/Ubuntu
sudo apt install libwebkit2gtk-4.1-0
# Fedora
sudo dnf install webkit2gtk4.1
# Arch
sudo pacman -S webkit2gtk-4.1
```
--------------------------------
### Setup Help Menu
Source: https://v3.wails.io/features/browser/integration
Create a help menu with options to open online documentation, the GitHub repository, or a new issue page in the browser. Display an error dialog if opening fails.
```go
// Create help menu
func setupHelpMenu(app *application.App) {
menu := app.Menu.New()
helpMenu := menu.AddSubmenu("Help")
helpMenu.Add("Online Documentation").OnClick(func(ctx *application.Context) {
err := app.Browser.OpenURL("https://docs.yourapp.com")
if err != nil {
app.Dialog.Error().
SetTitle("Error").
SetMessage("Could not open documentation").
Show()
}
})
helpMenu.Add("GitHub Repository").OnClick(func(ctx *application.Context) {
app.Browser.OpenURL("https://github.com/youruser/yourapp")
})
helpMenu.Add("Report Issue").OnClick(func(ctx *application.Context) {
app.Browser.OpenURL("https://github.com/youruser/yourapp/issues/new")
})
}
```
--------------------------------
### Complete Environment Management Example
Source: https://v3.wails.io/features/environment/info
This example demonstrates setting up an application based on the detected environment, monitoring theme changes, and creating menus with environment-specific features. It logs environment details and configures themes accordingly.
```go
package main
import (
"fmt"
"os"
"path/filepath"
"runtime"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
)
func main() {
app := application.New(application.Options{
Name: "Environment Demo",
})
// Setup application based on environment
setupForEnvironment(app)
// Monitor theme changes
monitorThemeChanges(app)
// Create menu with environment features
setupEnvironmentMenu(app)
// Create main window
window := app.Window.New()
window.SetTitle("Environment Demo")
err := app.Run()
if err != nil {
panic(err)
}
}
func setupForEnvironment(app *application.App) {
envInfo := app.Env.Info()
app.Logger.Info("Application environment",
"os", envInfo.OS,
"arch", envInfo.Arch,
"debug", envInfo.Debug,
"darkMode", app.Env.IsDarkMode(),
)
// Configure for platform
switch envInfo.OS {
case "darwin":
app.Logger.Info("Configuring for macOS")
// macOS-specific setup
case "windows":
app.Logger.Info("Configuring for Windows")
// Windows-specific setup
case "linux":
app.Logger.Info("Configuring for Linux")
// Linux-specific setup
}
// Apply initial theme
if app.Env.IsDarkMode() {
applyDarkTheme(app)
} else {
applyLightTheme(app)
}
}
func monitorThemeChanges(app *application.App) {
app.Event.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) {
if app.Env.IsDarkMode() {
app.Logger.Info("System switched to dark mode")
applyDarkTheme(app)
} else {
app.Logger.Info("System switched to light mode")
applyLightTheme(app)
}
})
}
func setupEnvironmentMenu(app *application.App) {
menu := app.Menu.New()
// Add platform-specific app menu
if runtime.GOOS == "darwin" {
menu.AddRole(application.AppMenu)
}
// Tools menu
toolsMenu := menu.AddSubmenu("Tools")
toolsMenu.Add("Show Environment Info").OnClick(func(ctx *application.Context) {
showEnvironmentInfo(app)
})
toolsMenu.Add("Open Downloads Folder").OnClick(func(ctx *application.Context) {
openDownloadsFolder(app)
})
toolsMenu.Add("Toggle Theme").OnClick(func(ctx *application.Context) {
// This would typically be handled by the system
// but shown here for demonstration
toggleTheme(app)
})
app.Menu.Set(menu)
}
func showEnvironmentInfo(app *application.App) {
envInfo := app.Env.Info()
message := fmt.Sprintf(`Environment Information:
Operating System: %s
Architecture: %s
Debug Mode: %t
Dark Mode: %t
Platform Details:`,
envInfo.OS,
envInfo.Arch,
envInfo.Debug,
app.Env.IsDarkMode())
for key, value := range envInfo.PlatformInfo {
message += fmt.Sprintf("\n%s: %v", key, value)
}
if envInfo.OSInfo != nil {
message += fmt.Sprintf("\n\nOS Information:\nName: %s\nVersion: %s",
envInfo.OSInfo.Name,
envInfo.OSInfo.Version)
}
dialog := app.Dialog.Info()
dialog.SetTitle("Environment Information")
dialog.SetMessage(message)
dialog.Show()
}
func openDownloadsFolder(app *application.App) {
homeDir, err := os.UserHomeDir()
if err != nil {
app.Logger.Error("Could not get home directory", "error", err)
return
}
downloadsDir := filepath.Join(homeDir, "Downloads")
err = app.Env.OpenFileManager(downloadsDir, false)
if err != nil {
app.Logger.Error("Could not open Downloads folder", "error", err)
app.Dialog.Error().
SetTitle("File Manager Error").
SetMessage("Could not open Downloads folder").
Show()
}
}
func applyDarkTheme(app *application.App) {
app.Logger.Info("Applying dark theme")
// Emit theme change to frontend
app.Event.Emit("theme:apply", "dark")
}
func applyLightTheme(app *application.App) {
app.Logger.Info("Applying light theme")
// Emit theme change to frontend
app.Event.Emit("theme:apply", "light")
}
func toggleTheme(app *application.App) {
// This is just for demonstration
// Real theme changes should come from the system
currentlyDark := app.Env.IsDarkMode()
if currentlyDark {
applyLightTheme(app)
} else {
applyDarkTheme(app)
}
}
```
--------------------------------
### Install Node.js using NodeSource (Ubuntu/Debian)
Source: https://v3.wails.io/quick-start/installation
Install Node.js using the NodeSource repository for Ubuntu and Debian-based systems. This ensures you get the latest LTS version.
```bash
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
```
--------------------------------
### Complete Window Configuration Example
Source: https://v3.wails.io/features/windows/options
Demonstrates a production-ready window configuration with identity, size, state, appearance, and platform-specific settings. Ensure frontend assets are served at the application level.
```go
package main
import (
_ "embed"
"github.com/wailsapp/wails/v3/pkg/application"
)
//go:embed frontend/dist
var assets embed.FS
//go:embed icon.png
var icon []byte
func main() {
app := application.New(application.Options{
Name: "My Application",
})
window := app.Window.NewWithOptions(application.WebviewWindowOptions{
// Identity
Name: "main-window",
Title: "My Application",
// Size and Position
Width: 1200,
Height: 800,
MinWidth: 800,
MinHeight: 600,
// Initial State
StartState: application.WindowStateNormal,
// Appearance
BackgroundColour: application.NewRGB(255, 255, 255),
// Platform-Specific (per-window structs)
Mac: application.MacWindow{
TitleBar: application.MacTitleBar{
AppearsTransparent: true,
},
Backdrop: application.MacBackdropTranslucent,
},
Windows: application.WindowsWindow{
BackdropType: application.Mica,
DisableIcon: false,
},
Linux: application.LinuxWindow{
Icon: icon,
},
})
window.Center()
window.Show()
app.Run()
}
```
--------------------------------
### Complete Application Menu Example
Source: https://v3.wails.io/guides/menus
A full example demonstrating how to create and set an application menu, including submenus and menu items with click handlers. It also shows how to set a custom menu for a specific window.
```go
func main() {
app := application.New(application.Options{})
// Create application menu
appMenu := app.Menu.New()
fileMenu := appMenu.AddSubmenu("File")
fileMenu.Add("New").OnClick(func(ctx *application.Context) {
// This will be available in all windows unless overridden
window := app.Window.Current()
window.SetTitle("New Window")
})
// Set as application menu - this is for macOS
app.Menu.Set(appMenu)
// Window with custom menu on Windows
customMenu := app.Menu.New()
customMenu.Add("Custom Action")
app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Custom Menu",
Windows: application.WindowsWindow{
Menu: customMenu,
},
})
app.Run()
}
```
--------------------------------
### Linux Installation Steps
Source: https://v3.wails.io/concepts/build-system
Commands to install a Wails application on Linux by copying the binary, desktop file, and icon to their respective system directories.
```bash
# Copy binary
sudo cp myapp /usr/bin/
# Copy desktop file
sudo cp myapp.desktop /usr/share/applications/
# Copy icon
sudo cp icon.png /usr/share/icons/hicolor/256x256/apps/myapp.png
```
--------------------------------
### Example ServeAssets Implementation
Source: https://v3.wails.io/guides/custom-transport
An example implementation of the `ServeAssets` method for a custom transport. It sets up an HTTP multiplexer to handle both IPC and Wails assets.
```go
func (t *MyTransport) ServeAssets(assetHandler http.Handler) error {
mux := http.NewServeMux()
// Mount your IPC endpoint
mux.HandleFunc("/my/ipc/endpoint", t.handleIPC)
// Mount Wails asset server for everything else
mux.Handle("/", assetHandler)
// Start HTTP server
t.httpServer.Handler = mux
go t.httpServer.ListenAndServe()
return nil
}
```
--------------------------------
### Run Wails Setup Wizard
Source: https://v3.wails.io/guides/build/signing
Initiates the Wails setup wizard to configure code signing. This wizard helps detect installed signing tools, list available certificates/keys, generate self-signed certificates for Windows, and securely store passwords.
```bash
wails3 setup
```
--------------------------------
### Autostart EnableWithOptions Example
Source: https://v3.wails.io/features/autostart/basics
Register the application to launch at login with custom options, such as overriding the identifier or adding extra arguments. This is useful for fine-tuning the autostart behavior.
```go
func (m *AutostartManager) EnableWithOptions(opts AutostartOptions) error
```
--------------------------------
### Run MCP Example Application
Source: https://v3.wails.io/guides/mcp-service
Navigate to the example application directory and run the Go build command with the 'mcp' tag enabled. This prepares the application for MCP client interaction.
```bash
cd v3/examples/mcp
go run -tags mcp .
```
--------------------------------
### Dynamic Server Request Example
Source: https://v3.wails.io/reference/update-manifest
Illustrates a GET request to a dynamic update server, including query parameters for platform, architecture, version, and channel.
```http
GET /check?platform=darwin&arch=arm64&version=1.0.0&channel=stable HTTP/1.1
Host: updates.example.com
```
--------------------------------
### Get All and Primary Screens
Source: https://v3.wails.io/features/screens/info
Retrieve all available screens and identify the primary display. Useful for multi-monitor setups or ensuring operations occur on the main screen.
```go
// Get all screens
screens := app.Screen.GetAll()
for _, screen := range screens {
fmt.Printf("Screen: %s (%dx%d)\n",
screen.Name, screen.Size.Width, screen.Size.Height)
}
// Get primary screen
primary := app.Screen.GetPrimary()
fmt.Printf("Primary: %s\n", primary.Name)
```
--------------------------------
### Create Multiple Windows with Options
Source: https://v3.wails.io/concepts/lifecycle
Demonstrates creating a main window and a settings window that starts hidden.
```go
mainWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Main Window",
})
settingsWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Settings",
Width: 400,
Height: 600,
Hidden: true, // Start hidden
})
```
--------------------------------
### Recommended Menu Setup with UseApplicationMenu
Source: https://v3.wails.io/features/menus/application
Set the application menu once and configure windows to inherit it for cross-platform consistency. This is the recommended approach.
```go
// Set the application menu once
app.Menu.Set(menu)
// Create windows that inherit the menu on Windows/Linux
app.Window.NewWithOptions(application.WebviewWindowOptions{
UseApplicationMenu: true, // Window uses the app menu
})
```
--------------------------------
### Develop Wails Documentation
Source: https://v3.wails.io/contributing/setup
Sets up and runs the development server for the Wails documentation. Installs dependencies, starts the dev server, and provides commands to build for production.
```bash
cd docs
# Install dependencies
npm install
# Start dev server
npm run dev
# Build for production
npm run build
```
--------------------------------
### Static Host Request Example
Source: https://v3.wails.io/reference/update-manifest
Shows a GET request to a static host using path parameters for platform, architecture, and channel, with version as a query parameter.
```http
GET /updates/darwin/arm64/stable.json?version=1.0.0 HTTP/1.1
Host: cdn.example.com
```
--------------------------------
### Wizard Dialog Implementation
Source: https://v3.wails.io/features/dialogs/custom
Provides the structure and methods for a multi-step wizard dialog, managing current step, data collection, and navigation. Suitable for guided setup processes.
```Go
type Wizarddialog struct {
window *application.WebviewWindow
currentStep int
data map[string]interface{}
done chan bool
}
func NewWizarddialog(app *application.App) *Wizarddialog {
wd := &Wizarddialog{
currentStep: 0,
data: make(map[string]interface{}),
done: make(chan bool, 1),
}
wd.window = app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Setup Wizard",
Width: 600,
Height: 400,
DisableResize: true,
})
return wd
}
func (wd *Wizarddialog) Show() (map[string]interface{}, bool) {
wd.window.Show()
ok := <-wd.done
return wd.data, ok
}
func (wd *Wizarddialog) NextStep(stepData map[string]interface{}) {
// Merge step data
for k, v := range stepData {
wd.data[k] = v
}
wd.currentStep++
wd.window.EmitEvent("next-step", wd.currentStep)
}
func (wd *Wizarddialog) PreviousStep() {
if wd.currentStep > 0 {
wd.currentStep--
wd.window.EmitEvent("previous-step", wd.currentStep)
}
}
func (wd *Wizarddialog) Finish(finalData map[string]interface{}) {
for k, v := range finalData {
wd.data[k] = v
}
wd.done <- true
wd.window.Close()
}
func (wd *Wizarddialog) Cancel() {
wd.done <- false
wd.window.Close()
}
```
--------------------------------
### Quick Start: Create and Show Custom Dialog
Source: https://v3.wails.io/features/dialogs/custom
This snippet demonstrates the basic steps to create a custom dialog window with specific options, load custom UI, and display it as a modal.
```go
// Create custom dialog window
dialog := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Custom dialog",
Width: 400,
Height: 300,
AlwaysOnTop: true,
Frameless: true,
Hidden: true,
})
// Load custom UI
dialog.SetURL("http://wails.localhost/dialog.html")
// Show as modal
dialog.Show()
dialog.Focus()
```
--------------------------------
### Standard Application Menu Example
Source: https://v3.wails.io/reference/menu
Demonstrates the creation of a comprehensive application menu with File, Edit, View, and Help submenus. Includes accelerators, separators, checkboxes, and radio buttons.
```Go
package main
import (
"github.com/wailsapp/wails/v3/pkg/application"
)
func createMenu(app *application.App) *application.Menu {
menu := app.NewMenu()
// File menu
fileMenu := menu.AddSubmenu("File")
fileMenu.Add("New").
SetAccelerator("Ctrl+N").
OnClick(func(ctx *application.Context) {
// Create new document
})
fileMenu.Add("Open").
SetAccelerator("Ctrl+O").
OnClick(func(ctx *application.Context) {
// Open file dialog
})
fileMenu.Add("Save").
SetAccelerator("Ctrl+S").
OnClick(func(ctx *application.Context) {
// Save document
})
fileMenu.AddSeparator()
fileMenu.Add("Exit").OnClick(func(ctx *application.Context) {
app.Quit()
})
// Edit menu
editMenu := menu.AddSubmenu("Edit")
editMenu.Add("Undo").SetAccelerator("Ctrl+Z")
editMenu.Add("Redo").SetAccelerator("Ctrl+Y")
editMenu.AddSeparator()
editMenu.Add("Cut").SetAccelerator("Ctrl+X")
editMenu.Add("Copy").SetAccelerator("Ctrl+C")
editMenu.Add("Paste").SetAccelerator("Ctrl+V")
// View menu
viewMenu := menu.AddSubmenu("View")
darkMode := viewMenu.AddCheckbox("Dark Mode", false)
darkMode.OnClick(func(ctx *application.Context) {
// Toggle dark mode
isChecked := darkMode.Checked()
app.Logger.Info("Dark mode", "enabled", isChecked)
})
viewMenu.AddSeparator()
viewMenu.AddRadio("List View", true)
viewMenu.AddRadio("Grid View", false)
viewMenu.AddRadio("Detail View", false)
// Help menu
helpMenu := menu.AddSubmenu("Help")
helpMenu.Add("Documentation").OnClick(func(ctx *application.Context) {
// Open docs
})
helpMenu.Add("About").OnClick(func(ctx *application.Context) {
// Show about dialog
})
return menu
}
func main() {
app := application.New(application.Options{
Name: "Menu Demo",
})
menu := createMenu(app)
app.Menu.Set(menu)
window := app.Window.New()
window.Show()
app.Run()
}
```
--------------------------------
### Complete Window Event Management Example
Source: https://v3.wails.io/features/windows/events
This example demonstrates a production-ready window with comprehensive event handling for focus, state changes, and position/size updates. It includes loading and saving window state to a JSON file.
```Go
package main
import (
"encoding/json"
"fmt"
"os"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
)
type WindowState struct {
X int `json:"x"`
Y int `json:"y"`
Width int `json:"width"`
Height int `json:"height"`
Maximised bool `json:"maximised"`
Fullscreen bool `json:"fullscreen"`
}
type ManagedWindow struct {
app *application.App
window *application.WebviewWindow
state WindowState
dirty bool
}
func main() {
app := application.New(application.Options{
Name: "Event Demo",
})
mw := &ManagedWindow{app: app}
mw.CreateWindow()
mw.LoadState()
mw.SetupEventHandlers()
app.Run()
}
func (mw *ManagedWindow) CreateWindow() {
mw.window = mw.app.Window.NewWithOptions(application.WebviewWindowOptions{
Name: "main",
Title: "Event Demo",
Width: 800,
Height: 600,
})
}
func (mw *ManagedWindow) SetupEventHandlers() {
// Focus events
mw.window.OnWindowEvent(events.Common.WindowFocus, func(e *application.WindowEvent) {
mw.window.EmitEvent("focus-state", true)
})
mw.window.OnWindowEvent(events.Common.WindowLostFocus, func(e *application.WindowEvent) {
mw.window.EmitEvent("focus-state", false)
})
// State change events
mw.window.OnWindowEvent(events.Common.WindowMinimise, func(e *application.WindowEvent) {
mw.SaveState()
})
mw.window.OnWindowEvent(events.Common.WindowMaximise, func(e *application.WindowEvent) {
mw.state.Maximised = true
mw.dirty = true
})
mw.window.OnWindowEvent(events.Common.WindowUnMaximise, func(e *application.WindowEvent) {
mw.state.Maximised = false
mw.dirty = true
})
mw.window.OnWindowEvent(events.Common.WindowFullscreen, func(e *application.WindowEvent) {
mw.state.Fullscreen = true
mw.dirty = true
})
mw.window.OnWindowEvent(events.Common.WindowUnFullscreen, func(e *application.WindowEvent) {
mw.state.Fullscreen = false
mw.dirty = true
})
// Position and size events
mw.window.OnWindowEvent(events.Common.WindowDidMove, func(e *application.WindowEvent) {
mw.state.X, mw.state.Y = mw.window.Position()
mw.dirty = true
})
mw.window.OnWindowEvent(events.Common.WindowDidResize, func(e *application.WindowEvent) {
mw.state.Width, mw.state.Height = mw.window.Size()
mw.dirty = true
})
// Cancellable close — use a hook, not a listener.
mw.window.RegisterHook(events.Common.WindowClosing, func(e *application.WindowEvent) {
if mw.dirty {
mw.SaveState()
}
})
}
func (mw *ManagedWindow) LoadState() {
data, err := os.ReadFile("window-state.json")
if err != nil {
return
}
if err := json.Unmarshal(data, &mw.state); err != nil {
return
}
// Restore window state
mw.window.SetPosition(mw.state.X, mw.state.Y)
mw.window.SetSize(mw.state.Width, mw.state.Height)
if mw.state.Maximised {
mw.window.Maximise()
}
if mw.state.Fullscreen {
mw.window.Fullscreen()
}
}
func (mw *ManagedWindow) SaveState() {
data, err := json.Marshal(mw.state)
if err != nil {
return
}
os.WriteFile("window-state.json", data, 0644)
mw.dirty = false
fmt.Println("Window state saved")
}
```
--------------------------------
### XDG Autostart Desktop Entry Example
Source: https://v3.wails.io/features/autostart/basics
This example shows the content of a `.desktop` file used for XDG autostart entries. It specifies the application type, whether it's hidden, and the command to execute, including arguments.
```ini
Type=Application
Hidden=false
X-GNOME-Autostart-enabled=true
Exec=