Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd12dd4e99 | ||
|
|
b044780e61 |
Generated
+1
-1
@@ -2948,7 +2948,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "portal"
|
||||
version = "0.3.31"
|
||||
version = "0.3.33"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "portal"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
|
||||
+29
@@ -40,6 +40,20 @@ pub fn shell(options: LeptosOptions) -> impl IntoView {
|
||||
// once loaded via <link>/<img> on Safari/iOS.
|
||||
<link rel="icon" media="(prefers-color-scheme: light)" href="/favicon-light.svg" type="image/svg+xml"/>
|
||||
<link rel="icon" media="(prefers-color-scheme: dark)" href="/favicon-dark.svg" type="image/svg+xml"/>
|
||||
// Fonts hide behind the stylesheet: the browser must
|
||||
// fetch and parse CSS before it discovers them. The
|
||||
// latin subset is on every page's critical path, so
|
||||
// announce it up front; latin-ext and vietnamese stay
|
||||
// unicode-range-gated and load only when script needs
|
||||
// them - preloading those would tax everyone for a few.
|
||||
// (Font preloads require crossorigin even same-origin.)
|
||||
<link
|
||||
rel="preload"
|
||||
href="/fonts/quicksand-semibold-latin.woff2"
|
||||
r#as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
// Server-side, so it can read hash.txt and link the
|
||||
// content-hashed stylesheet (hash-files = true).
|
||||
<HashedStylesheet id="leptos" options=options.clone()/>
|
||||
@@ -89,6 +103,19 @@ pub fn App() -> impl IntoView {
|
||||
.and_then(|s| s.stylesheet)
|
||||
.map(|p| format!("/site/{p}"))
|
||||
});
|
||||
// The wordmark paints in the hero on first view; announcing it in
|
||||
// the head starts the fetch during hydration instead of after. On
|
||||
// redoal.com it lives on the content host, so a preconnect opens
|
||||
// that TLS session while the preload is still queued.
|
||||
let wordmark_href = Memo::new(move |_| {
|
||||
site.get().and_then(|r| r.ok()).and_then(|s| s.wordmark)
|
||||
});
|
||||
let wordmark_origin = Memo::new(move |_| {
|
||||
wordmark_href.get().and_then(|w| {
|
||||
let rest = w.strip_prefix("https://")?;
|
||||
Some(format!("https://{}", rest.split('/').next()?))
|
||||
})
|
||||
});
|
||||
// A content-shipped favicon overrides the built-in one; injected
|
||||
// into the head after the static defaults, so it wins.
|
||||
let favicon = Memo::new(move |_| {
|
||||
@@ -100,6 +127,8 @@ pub fn App() -> impl IntoView {
|
||||
|
||||
view! {
|
||||
<Html attr:lang=move || lang.get()/>
|
||||
{move || wordmark_origin.get().map(|href| view! { <Link rel="preconnect" href=href crossorigin="anonymous"/> })}
|
||||
{move || wordmark_href.get().map(|href| view! { <Link rel="preload" as_="image" href=href/> })}
|
||||
{move || custom_css.get().map(|href| view! { <Stylesheet id="site-custom" href=href/> })}
|
||||
{move || favicon.get().map(|href| view! { <Link rel="icon" href=href/> })}
|
||||
<Suspense fallback=|| ()>
|
||||
|
||||
Reference in New Issue
Block a user