Tokamak icon indicating copy to clipboard operation
Tokamak copied to clipboard

Allow modifying the `<head>` DOM element

Open MaxDesiatov opened this issue 3 years ago • 10 comments

The main use case would be in modifying the <title> value and adding styles/scripts declaratively with support for the TokamakStaticHTML renderer. I'm more inclined towards adding the HTMLHead type conforming to Scene, to which one could add HTML views with whatever content they want.

MaxDesiatov avatar Aug 27 '20 16:08 MaxDesiatov

So it'd be like this?:

struct MyApp : App {
  var body: some Scene {
    HTMLHead {
      HTML("meta", [...])
    }
    WindowGroup("MyApp") {
      ContentView()
    }
  }
}

If so, I'm all for it being a Scene.

carson-katri avatar Aug 27 '20 16:08 carson-katri

Yes, exactly. If there's a need for a given view (or Router) to adjust anything (most of the time it would be the <title> content) a given App could expose it as an environment object for example.

MaxDesiatov avatar Aug 27 '20 16:08 MaxDesiatov

most of the time it would be the <title> content

Since macOS already has the concept of a title for a window, shouldn’t we implement that API to enable setting the title?

j-f1 avatar Aug 27 '20 17:08 j-f1

That's a great point, but I previously haven't written any SwiftUI apps for macOS, so I don't even know how that's supposed to work to propose anything concrete on that front. I obviously would prefer using that if it fits well for our purposes.

MaxDesiatov avatar Aug 27 '20 17:08 MaxDesiatov

We have it, it's the String/Text argument passed to the WindowGroup initializer: WindowGroup("My Site Title") { ... }

(At least that's how we set the title now)

carson-katri avatar Aug 27 '20 17:08 carson-katri

Right, I started thinking of <head> because I tried to imagine how <title> changes could be integrated with the new router, I'm not sure it would be that easy if the only way to set a title is via the WindowGroup argument. Unless we add an explicit title binding initializer argument to the Router type?

MaxDesiatov avatar Aug 27 '20 17:08 MaxDesiatov

Ah, ok. So in SwiftUI I think the only way to do it before macOS 11 was via the AppDelegate. So using the HTMLHead would probably be best in that case.

carson-katri avatar Aug 27 '20 17:08 carson-katri

IDK, the title can be dynamic already if only the router supported title bindings:

struct MyApp : App {
  @State var title: String

  var body: some Scene {
    WindowGroup(title) {
      Router(title: $title) {
        // more routes here, but unclear yet how they adjust the title
      }
    }
  }
}

This is just a surface of the potential Router API for this, a proper EnvironmentObject might work better? The point is that HTMLHead is probably not required for supporting dynamic titles if we can already pass a title as a WindowGroup argument. The primary use of HTMLHead would be in adding styles/scripts/fonts then.

And adjusting it via WindowGroup is more compatible with SwiftUI, which is a strong argument to me personally.

MaxDesiatov avatar Aug 27 '20 17:08 MaxDesiatov

I'd probably provide a Binding to the activeRoute not a title string. The title string could then be made via a switch statement.

carson-katri avatar Aug 27 '20 17:08 carson-katri

I'll open an issue in the repo.

carson-katri avatar Aug 27 '20 17:08 carson-katri