Integrasi Browser
Wails menyediakan integrasi browser sederhana melalui API BrowserManager, memungkinkan aplikasi Anda membuka URL dan file di browser web default pengguna. Ini berguna untuk membuka tautan eksternal, dokumentasi, atau file yang seharusnya ditangani oleh browser.
Mengakses Browser Manager
Section titled “Mengakses Browser Manager”Browser manager diakses melalui properti Browser pada instance aplikasi Anda:
app := application.New(application.Options{ Name: "Browser Integration Demo",})
// Access the browser managerbrowser := app.BrowserMembuka URL
Section titled “Membuka URL”Buka URL Web
Section titled “Buka URL Web”Buka URL di browser web default pengguna:
// Open a websiteerr := app.Browser.OpenURL("https://wails.io")if err != nil { app.Logger.Error("Failed to open URL", "error", err)}
// Open specific pageserr = app.Browser.OpenURL("https://github.com/wailsapp/wails")if err != nil { app.Logger.Error("Failed to open GitHub", "error", err)}Buka URL Lokal
Section titled “Buka URL Lokal”Buka server development lokal atau resource jaringan lokal:
// Open local development servererr := app.Browser.OpenURL("http://localhost:3000")if err != nil { app.Logger.Error("Failed to open local server", "error", err)}
// Open network resourceerr = app.Browser.OpenURL("http://192.168.1.100:8080")if err != nil { app.Logger.Error("Failed to open network resource", "error", err)}Membuka File
Section titled “Membuka File”Buka File HTML
Section titled “Buka File HTML”Buka file HTML lokal di browser:
// Open an HTML fileerr := app.Browser.OpenFile("/path/to/documentation.html")if err != nil { app.Logger.Error("Failed to open HTML file", "error", err)}
// Open generated reportsreportPath := "/tmp/report.html"err = app.Browser.OpenFile(reportPath)if err != nil { app.Logger.Error("Failed to open report", "error", err)}Buka Tipe File Lain
Section titled “Buka Tipe File Lain”Buka berbagai tipe file yang dapat ditangani browser:
// Open PDF fileserr := app.Browser.OpenFile("/path/to/document.pdf")if err != nil { app.Logger.Error("Failed to open PDF", "error", err)}
// Open image fileserr = app.Browser.OpenFile("/path/to/image.png")if err != nil { app.Logger.Error("Failed to open image", "error", err)}
// Open text fileserr = app.Browser.OpenFile("/path/to/readme.txt")if err != nil { app.Logger.Error("Failed to open text file", "error", err)}Kasus Penggunaan Umum
Section titled “Kasus Penggunaan Umum”Bantuan dan Dokumentasi
Section titled “Bantuan dan Dokumentasi”Sediakan akses mudah ke resource bantuan:
// Create help menufunc 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") })}Tautan Eksternal dalam Konten
Section titled “Tautan Eksternal dalam Konten”Tangani tautan eksternal dari konten aplikasi Anda:
func handleExternalLink(app *application.App, url string) { // Validate the URL before opening if !isValidURL(url) { app.Logger.Warn("Invalid URL", "url", url) return }
// Optionally confirm with user dialog := app.Dialog.Question() dialog.SetTitle("Open External Link") dialog.SetMessage(fmt.Sprintf("Open %s in your browser?", url))
dialog.AddButton("Open").OnClick(func() { err := app.Browser.OpenURL(url) if err != nil { app.Logger.Error("Failed to open URL", "url", url, "error", err) } })
dialog.AddButton("Cancel") dialog.Show()}
func isValidURL(rawURL string) bool { parsed, err := url.Parse(rawURL) return err == nil && (parsed.Scheme == "http" || parsed.Scheme == "https")}Ekspor dan Lihat Laporan
Section titled “Ekspor dan Lihat Laporan”Buat dan buka laporan di browser:
import ( "html/template" "os" "path/filepath")
func generateAndOpenReport(app *application.App, data interface{}) error { // Create temporary file for the report tmpDir := os.TempDir() reportPath := filepath.Join(tmpDir, "report.html")
// Generate HTML report tmpl := `<!DOCTYPE html><html><head> <title>Application Report</title> <style> body { font-family: Arial, sans-serif; margin: 40px; } .header { border-bottom: 2px solid #333; padding-bottom: 10px; } .data { margin-top: 20px; } </style></head><body> <div class="header"> <h1>Application Report</h1> <p>Generated: {{.Timestamp}}</p> </div> <div class="data"> <!-- Report content here --> {{range .Items}} <p>{{.}}</p> {{end}} </div></body></html>`
// Write report to file file, err := os.Create(reportPath) if err != nil { return err } defer file.Close()
t, err := template.New("report").Parse(tmpl) if err != nil { return err }
err = t.Execute(file, data) if err != nil { return err }
// Open in browser return app.Browser.OpenFile(reportPath)}Alat Development
Section titled “Alat Development”Buka resource development selama development:
func setupDevelopmentMenu(app *application.App) { if !app.Env.Info().Debug { return // Only show in debug mode }
menu := app.Menu.New() devMenu := menu.AddSubmenu("Development")
devMenu.Add("Open DevTools").OnClick(func(ctx *application.Context) { // This would open browser devtools if available window := app.Window.Current() if window != nil { window.OpenDevTools() } })
devMenu.Add("View Source").OnClick(func(ctx *application.Context) { // Open source code repository app.Browser.OpenURL("https://github.com/youruser/yourapp") })
devMenu.Add("API Documentation").OnClick(func(ctx *application.Context) { // Open local API docs app.Browser.OpenURL("http://localhost:8080/docs") })}Penanganan Error
Section titled “Penanganan Error”Penanganan Error yang Graceful
Section titled “Penanganan Error yang Graceful”Selalu tangani error potensial saat membuka URL atau file:
func openURLWithFallback(app *application.App, url string, fallbackMessage string) { err := app.Browser.OpenURL(url) if err != nil { app.Logger.Error("Failed to open URL", "url", url, "error", err)
// Show fallback dialog with URL dialog := app.Dialog.Info() dialog.SetTitle("Unable to Open Link") dialog.SetMessage(fmt.Sprintf("%s\n\nURL: %s", fallbackMessage, url)) dialog.Show() }}
// UsageopenURLWithFallback(app, "https://docs.example.com", "Please open the following URL manually in your browser:")Umpan Balik Pengguna
Section titled “Umpan Balik Pengguna”Berikan umpan balik saat operasi berhasil atau gagal:
func openURLWithFeedback(app *application.App, url string) { err := app.Browser.OpenURL(url) if err != nil { // Show error dialog app.Dialog.Error(). SetTitle("Browser Error"). SetMessage(fmt.Sprintf("Could not open URL: %s", err.Error())). Show() } else { // Optionally show success notification app.Logger.Info("URL opened successfully", "url", url) }}Pertimbangan Platform
Section titled “Pertimbangan Platform”Di macOS:
- Menggunakan perintah
openuntuk meluncurkan browser default - Menghormati pengaturan browser default pengguna di System Preferences
- Dapat meminta permission jika aplikasi di-sandbox
- Menangani URL
file://dengan benar untuk file lokal
Di Windows:
- Menggunakan Windows Shell API untuk membuka URL
- Menghormati pengaturan browser default di Windows Settings
- Menangani format path Windows dengan benar
- Dapat menampilkan peringatan keamanan untuk URL tidak tepercaya
Di Linux:
- Mencoba menggunakan
xdg-openterlebih dahulu, fallback ke metode lain - Perilaku bervariasi menurut desktop environment
- Menghormati variabel environment
BROWSERjika disetel - Dapat memerlukan paket tambahan di instalasi minimal
Praktik Terbaik
Section titled “Praktik Terbaik”-
Selalu Tangani Error: Operasi browser dapat gagal karena berbagai alasan:
if err := app.Browser.OpenURL(url); err != nil {app.Logger.Error("Failed to open browser", "error", err)// Provide fallback or user notification} -
Validate URLs: Ensure URLs are well-formed before opening:
func isValidHTTPURL(str string) bool {u, err := url.Parse(str)return err == nil && (u.Scheme == "http" || u.Scheme == "https")} -
User Confirmation: For external links, consider asking user permission:
// Show confirmation dialog before opening external linksconfirmAndOpen(app, "https://external-site.com") -
Secure File Paths: When opening files, ensure paths are safe:
func openSafeFile(app *application.App, filename string) error {// Ensure file exists and is readableif _, err := os.Stat(filename); err != nil {return err}return app.Browser.OpenFile(filename)}
Complete Example
Section titled “Complete Example”Here’s a complete example showing various browser integration patterns:
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 := `<!DOCTYPE html><html><head> <title>Demo Report</title> <style> body { font-family: Arial, sans-serif; margin: 40px; } .header { color: #333; border-bottom: 1px solid #ccc; } </style></head><body> <div class="header"> <h1>Application Report</h1> <p>This is a sample report generated by the application.</p> </div> <div class="content"> <h2>Report Details</h2> <p>This report was generated to demonstrate browser integration.</p> </div></body></html>`
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()}