How to make content in WkWebView display in dark mode?

27 Views Asked by At

I would like to inject CSS code to display the web page in dark mode using WebKit on MacOS. The closest I can achieve is the code below, which seems to load CSS first (I can see a black screen for a second), and then it gets overwritten by the web content (YouTube.com), which is not in dark mode.

Ideally, I'd like to have it display dark mode when it detects the system

import SwiftUI
import WebKit

struct ContentView: View {
    @Environment(\.colorScheme) var colorScheme
    
    let webView = WebView()
    
    var body: some View {
        webView
            .toolbar {
                Spacer()
                
                Text("MacTube")
                    .padding(.leading, 110)
                
                Spacer()
                
                Button(action: {
                    self.webView.wkWebView.goBack()
                }, label: {
                    Image(systemName: "chevron.left")
                })
                
                Button(action: {
                    self.webView.wkWebView.goForward()
                }, label: {
                    Image(systemName: "chevron.right")
                })
                
                Button(action: {
                    self.webView.wkWebView.reload()
                }, label: {
                    Image(systemName: "arrow.clockwise")
                })
            }
            .background(Color(colorScheme == .dark
                ? CGColor(red: 0.097, green: 0.097, blue: 0.097, alpha: 1)
                : CGColor(red: 1, green: 1, blue: 1, alpha: 1)
            ))
    }
}

struct WebView: NSViewRepresentable {
    let wkWebView = WKWebView()
    
    func makeNSView(context: Context) -> WKWebView {
        let cssString = "@media(prefers-color-scheme: dark) {:root { color-scheme: dark; } body {color: white; background: black}}"
        let javascriptString = "var style = document.createElement('style'); style.innerHTML = '\(cssString)'; document.head.appendChild(style);"
        wkWebView.evaluateJavaScript(javascriptString, completionHandler: nil)
        return wkWebView
    }
    
    func updateNSView(_ nsView: WKWebView, context: Context) {
        let url = URL(string: "https://www.youtube.com")
        let urlRequest = URLRequest(url: url!)
        
        nsView.load(urlRequest)
    }
}
0

There are 0 best solutions below