OS26 SwiftUI WebView - Go Forward/Back?

Trying to implement my own forward/back buttons for the new SwiftUI WebView and reading the documentation I’m totally lost.

What’s the recommended way of implementing forward/back behavior with this component?

Answered by DTS Engineer in 847032022

Hi. Here's an example (borrowed from one of engineering's test apps) showing how you can implement back/forward buttons on a SwiftUI WebView:


/* first define the back/forward menu view */

private struct ToolbarBackForwardMenuView: View {
    struct LabelConfiguration {
        let text: String
        let systemImage: String
        let key: KeyEquivalent
    }

    let list: [WebPage.BackForwardList.Item]
    let label: LabelConfiguration
    let navigateToItem: (WebPage.BackForwardList.Item) -> Void

    var body: some View {
        Menu {
            ForEach(list) { item in
                Button(item.title ?? item.url.absoluteString) {
                    navigateToItem(item)
                }
            }
        } label: {
            Label(label.text, systemImage: label.systemImage)
                .labelStyle(.iconOnly)
        } primaryAction: {
            navigateToItem(list.first!)
        }
        .menuIndicator(.hidden)
        .disabled(list.isEmpty)
        .keyboardShortcut(label.key)
    }
}


/* then add a toolbar to your web view with back/forward buttons*/

WebView(viewModel.page)

....other stuff here ...

.toolbar {
	ToolbarItemGroup(placement: Self.navigationToolbarItemPlacement) {
		ToolbarBackForwardMenuView(
			list: viewModel.page.backForwardList.backList.reversed(),
			label: .init(text: "Backward", systemImage: "chevron.backward", key: "[")
		) {
			viewModel.page.load($0)
		}

		#if os(iOS)
		Spacer()
		#endif

		ToolbarBackForwardMenuView(
			list: viewModel.page.backForwardList.forwardList,
			label: .init(text: "Forward", systemImage: "chevron.forward", key: "]")
		) {
			viewModel.page.load($0)
		}

	}
	
	ToolbarItemGroup(placement: .principal) {
		PrincipalToolbarGroup()
	}
}

Hi. Here's an example (borrowed from one of engineering's test apps) showing how you can implement back/forward buttons on a SwiftUI WebView:


/* first define the back/forward menu view */

private struct ToolbarBackForwardMenuView: View {
    struct LabelConfiguration {
        let text: String
        let systemImage: String
        let key: KeyEquivalent
    }

    let list: [WebPage.BackForwardList.Item]
    let label: LabelConfiguration
    let navigateToItem: (WebPage.BackForwardList.Item) -> Void

    var body: some View {
        Menu {
            ForEach(list) { item in
                Button(item.title ?? item.url.absoluteString) {
                    navigateToItem(item)
                }
            }
        } label: {
            Label(label.text, systemImage: label.systemImage)
                .labelStyle(.iconOnly)
        } primaryAction: {
            navigateToItem(list.first!)
        }
        .menuIndicator(.hidden)
        .disabled(list.isEmpty)
        .keyboardShortcut(label.key)
    }
}


/* then add a toolbar to your web view with back/forward buttons*/

WebView(viewModel.page)

....other stuff here ...

.toolbar {
	ToolbarItemGroup(placement: Self.navigationToolbarItemPlacement) {
		ToolbarBackForwardMenuView(
			list: viewModel.page.backForwardList.backList.reversed(),
			label: .init(text: "Backward", systemImage: "chevron.backward", key: "[")
		) {
			viewModel.page.load($0)
		}

		#if os(iOS)
		Spacer()
		#endif

		ToolbarBackForwardMenuView(
			list: viewModel.page.backForwardList.forwardList,
			label: .init(text: "Forward", systemImage: "chevron.forward", key: "]")
		) {
			viewModel.page.load($0)
		}

	}
	
	ToolbarItemGroup(placement: .principal) {
		PrincipalToolbarGroup()
	}
}

I want to accept the answer as it was very helpful for understanding how to use the new WebPage object, but as of beta4 this is still not functioning in a way that is deliverable to end users.

hey yall did figure it out? We’re encountering the same issue on our side. When we add the button (using a similar implementation), the “Go Back” action seems to render outside of the web view we’re calling, rather than staying contained within it. Ideally, this should be handled inside the code (likely within the correct container or navigation context), but this behavior may depend on how the hosting infrastructure is set up.

Is it necessary to call an API or handle a specific callback before rendering the button? From what I understand, Swift and WebKit can support multiple integration approaches, but I’m wondering if there’s a recommended or more standardized way to handle this scenario.

OS26 SwiftUI WebView - Go Forward/Back?
 
 
Q