diff --git a/cbits-uikit/AppDelegate.m b/cbits-uikit/AppDelegate.m
--- a/cbits-uikit/AppDelegate.m
+++ b/cbits-uikit/AppDelegate.m
@@ -109,6 +109,15 @@
     callWithCString([deviceTokenString UTF8String], global_didRegisterForRemoteNotificationsWithDeviceToken);
 }
 
+- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
+    // Sent when the application receives remote notifications in the foreground or background
+    // TODO Allow a configurable CString -> IO () to be passed into AppDelegateConfig
+    if ([userInfo valueForKeyPath:@"aps.badge"] != nil) {
+        [UIApplication sharedApplication].applicationIconBadgeNumber=[[[userInfo objectForKey:@"aps"] objectForKey:@"badge"] intValue];
+    }
+    completionHandler(UIBackgroundFetchResultNewData);
+}
+
 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
     // Sent to the delegate when Apple Push Notification service cannot successfully complete the registration process.
     NSString *errorString = [error localizedDescription];
diff --git a/cbits/WKWebView.m b/cbits/WKWebView.m
--- a/cbits/WKWebView.m
+++ b/cbits/WKWebView.m
@@ -61,9 +61,9 @@
 
     if(!navigationAction.targetFrame && ![url.scheme isEqualToString:@"file"]) {
         if(openApp(url))
-		    decisionHandler(WKNavigationActionPolicyCancel);
-		else
-		    decisionHandler(WKNavigationActionPolicyAllow);
+            decisionHandler(WKNavigationActionPolicyCancel);
+         else
+            decisionHandler(WKNavigationActionPolicyAllow);
     }
     else
         decisionHandler(WKNavigationActionPolicyAllow);
@@ -74,6 +74,9 @@
 void addJSaddleHandler(WKWebView *webView, HsStablePtr startHandler, HsStablePtr resultHandler, HsStablePtr syncHandler) {
     JSaddleHandler * handler = [[JSaddleHandler alloc] initHandler:startHandler resultHandler:resultHandler syncHandler:syncHandler];
     [[[webView configuration] userContentController] addScriptMessageHandler:handler name:@"jsaddle"];
+#ifdef USE_UIKIT
+    webView.scrollView.bounces = NO;
+#endif
     webView.navigationDelegate = handler;
     webView.UIDelegate = handler;
 }
@@ -92,10 +95,11 @@
     handler.completionHandler = NULL;
 }
 
-void loadHTMLString(WKWebView *webView, const char * _Nonnull html) {
-    NSString *htmlString = [NSString stringWithCString:html encoding:NSUTF8StringEncoding];
-    dispatch_async(dispatch_get_main_queue(), ^{
-        [webView loadHTMLString:htmlString baseURL:NULL];
+void loadHTMLStringWithBaseURL(WKWebView *webView, const char * _Nonnull html, const char * _Nonnull url) {
+  NSString *htmlString = [NSString stringWithCString:html encoding:NSUTF8StringEncoding];
+  NSURL *baseURL = [NSURL URLWithString:[[NSString alloc] initWithCString:url encoding:NSUTF8StringEncoding]];
+  dispatch_async(dispatch_get_main_queue(), ^{
+      [webView loadHTMLString:htmlString baseURL:baseURL];
     });
 }
 
@@ -118,6 +122,3 @@
         }
     }
 }
-
-
-
diff --git a/jsaddle-wkwebview.cabal b/jsaddle-wkwebview.cabal
--- a/jsaddle-wkwebview.cabal
+++ b/jsaddle-wkwebview.cabal
@@ -1,5 +1,5 @@
 name: jsaddle-wkwebview
-version: 0.9.4.0
+version: 0.9.6.0
 cabal-version: >=1.10
 build-type: Simple
 license: MIT
@@ -25,32 +25,39 @@
 library
     exposed-modules:
         Language.Javascript.JSaddle.WKWebView
-        Language.Javascript.JSaddle.WKWebView.Internal
     build-depends:
-        aeson >=0.8.0.2 && <1.3,
-        base <5,
-        bytestring >=0.10.6.0 && <0.11,
-        jsaddle >= 0.9.4.0 && <0.10,
-        data-default,
-        containers
+        base <5
     default-language: Haskell2010
     hs-source-dirs: src
     frameworks: Foundation, WebKit
     ghc-options: -ferror-spans -Wall
-    c-sources:
-        cbits/WKWebView.m
     if impl(ghcjs)
         hs-source-dirs: src-ghcjs
     else
+        build-depends:
+            aeson >=0.8.0.2 && <1.5,
+            bytestring >=0.10.6.0 && <0.11,
+            directory,
+            jsaddle >= 0.9.4.0 && <0.10,
+            text,
+            data-default,
+            containers
+        exposed-modules:
+            Language.Javascript.JSaddle.WKWebView.Internal
         hs-source-dirs: src-ghc
+        c-sources:
+            cbits/WKWebView.m
+        cc-options: -Wno-everything
         if os(ios)
             frameworks: UIKit, UserNotifications
             if flag(include-app-delegate)
               c-sources:
                   cbits-uikit/AppDelegate.m
                   cbits-uikit/ViewController.m
+              cpp-options: -DUSE_UIKIT
         else
             frameworks: Cocoa
             if flag(include-app-delegate)
               c-sources:
                   cbits-cocoa/AppDelegate.m
+              cpp-options: -DUSE_COCOA
diff --git a/src-ghc/Language/Javascript/JSaddle/WKWebView.hs b/src-ghc/Language/Javascript/JSaddle/WKWebView.hs
--- a/src-ghc/Language/Javascript/JSaddle/WKWebView.hs
+++ b/src-ghc/Language/Javascript/JSaddle/WKWebView.hs
@@ -1,9 +1,12 @@
 module Language.Javascript.JSaddle.WKWebView
     ( jsaddleMain
+    , jsaddleMainHTMLWithBaseURL
     , jsaddleMainFile
     , WKWebView(..)
     , run
+    , run'
     , runWithAppConfig
+    , runHTMLWithBaseURL
     , runFile
     , mainBundleResourcePath
     , AppDelegateConfig (..)
@@ -17,7 +20,8 @@
 import qualified Data.Set as Set
 import Data.Word
 import Foreign.Marshal.Utils (fromBool)
-import Language.Javascript.JSaddle.WKWebView.Internal (jsaddleMain, jsaddleMainFile, WKWebView(..), mainBundleResourcePath)
+import Language.Javascript.JSaddle.WKWebView.Internal
+       (jsaddleMain, jsaddleMainHTMLWithBaseURL, jsaddleMainFile, WKWebView(..), mainBundleResourcePath)
 import System.Environment (getProgName)
 import Foreign.C.String (CString, withCString)
 import Foreign.StablePtr (StablePtr, newStablePtr)
@@ -96,29 +100,38 @@
 
 -- | Run JSaddle in a WKWebView
 run :: JSM () -> IO ()
-run = run' Nothing def
+run f = run' def (jsaddleMain f)
 
 -- | Run JSaddle in a WKWebView
 runWithAppConfig :: AppDelegateConfig -> JSM () -> IO ()
-runWithAppConfig = run' Nothing
+runWithAppConfig cfg = run' cfg . jsaddleMain
 
 -- | Run JSaddle in a WKWebView first loading the specified file
 --   from the mainBundle (relative to the resourcePath).
-runFile :: ByteString -- ^ The file to navigate to.
-        -> ByteString -- ^ The path to allow read access to.
-        -> AppDelegateConfig
-        -> JSM ()
-        -> IO ()
-runFile url allowing = run' $ Just (url, allowing)
+runFile
+  :: ByteString -- ^ The file to navigate to.
+  -> ByteString -- ^ The path to allow read access to.
+  -> AppDelegateConfig
+  -> JSM ()
+  -> IO ()
+runFile url allowing cfg = run' cfg . jsaddleMainFile url allowing
 
-run' :: Maybe (ByteString, ByteString)
-     -> AppDelegateConfig
-     -> JSM ()
+-- | Run JSaddle in a WKWebView first loading the specified html
+--   as though it came from the specified URL
+--   (calls WKWebKit function loadHTMLString).
+runHTMLWithBaseURL
+  :: ByteString -- ^ HTML to load.
+  -> ByteString -- ^ pretend it came from this URL.
+  -> AppDelegateConfig
+  -> JSM ()
+  -> IO ()
+runHTMLWithBaseURL url allowing cfg = run' cfg . jsaddleMainHTMLWithBaseURL url allowing
+
+run' :: AppDelegateConfig
+     -> (WKWebView -> IO ())
      -> IO ()
-run' mUrl cfg f = do
-    handler <- case mUrl of
-      Just (url, allowing) -> newStablePtr (jsaddleMainFile url allowing f)
-      Nothing -> newStablePtr (jsaddleMain f)
+run' cfg main = do
+    handler <- newStablePtr main
     progName <- getProgName
 
     -- AppDelegate callbacks
diff --git a/src/Language/Javascript/JSaddle/WKWebView/Internal.hs b/src/Language/Javascript/JSaddle/WKWebView/Internal.hs
--- a/src/Language/Javascript/JSaddle/WKWebView/Internal.hs
+++ b/src/Language/Javascript/JSaddle/WKWebView/Internal.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE ForeignFunctionInterface, OverloadedStrings #-}
 module Language.Javascript.JSaddle.WKWebView.Internal
     ( jsaddleMain
+    , jsaddleMainHTMLWithBaseURL
     , jsaddleMainFile
     , WKWebView(..)
     , mainBundleResourcePath
@@ -15,6 +16,8 @@
 import qualified Data.ByteString as BS (ByteString)
 import Data.ByteString.Lazy (ByteString, toStrict, fromStrict)
 import Data.Aeson (encode, decode)
+import qualified Data.Text as T (pack)
+import Data.Text.Encoding (encodeUtf8)
 
 import Foreign.C.String (CString)
 import Foreign.Ptr (Ptr, nullPtr)
@@ -24,6 +27,8 @@
 import Language.Javascript.JSaddle.Run (runJavaScript)
 import Language.Javascript.JSaddle.Run.Files (initState, runBatch, ghcjsHelpers)
 
+import System.Directory (getCurrentDirectory)
+
 newtype WKWebView = WKWebView (Ptr WKWebView)
 newtype JSaddleHandler = JSaddleHandler (Ptr JSaddleHandler)
 
@@ -34,7 +39,7 @@
 foreign export ccall callWithCString :: CString -> StablePtr (CString -> IO ()) -> IO ()
 foreign export ccall callIO :: StablePtr (IO ()) -> IO ()
 foreign import ccall addJSaddleHandler :: WKWebView -> StablePtr (IO ()) -> StablePtr (Results -> IO ()) -> StablePtr (Results -> IO Batch) -> IO ()
-foreign import ccall loadHTMLString :: WKWebView -> CString -> IO ()
+foreign import ccall loadHTMLStringWithBaseURL :: WKWebView -> CString -> CString -> IO ()
 foreign import ccall loadBundleFile :: WKWebView -> CString -> CString -> IO ()
 foreign import ccall evaluateJavaScript :: WKWebView -> CString -> IO ()
 foreign import ccall completeSync :: JSaddleHandler -> CString -> IO ()
@@ -42,9 +47,23 @@
 
 -- | Run JSaddle in WKWebView
 jsaddleMain :: JSM () -> WKWebView -> IO ()
-jsaddleMain f webView =
+jsaddleMain f webView = do
+    pwd <- getCurrentDirectory
+    let baseURL = encodeUtf8 $ "file://" <> T.pack pwd <> "/index.html"
+    jsaddleMainHTMLWithBaseURL (toStrict indexHtml) baseURL f webView
+
+-- | Run JSaddle in WKWebView with initial html and base url
+jsaddleMainHTMLWithBaseURL
+  :: BS.ByteString -- ^ HTML
+  -> BS.ByteString -- ^ Base URL
+  -> JSM ()
+  -> WKWebView
+  -> IO ()
+jsaddleMainHTMLWithBaseURL initialHTML baseURL f webView =
     jsaddleMain' f webView $
-        useAsCString (toStrict indexHtml) $ loadHTMLString webView
+        useAsCString baseURL $ \url ->
+            useAsCString initialHTML $ \html ->
+                loadHTMLStringWithBaseURL webView html url
 
 -- | Run JSaddle in a WKWebView first loading the specified file
 --   from the mainBundle (relative to the resourcePath).
@@ -140,4 +159,3 @@
     if bs == nullPtr
         then return Nothing
         else Just <$> packCString bs
-
