lighthouse fixes
This commit is contained in:
@@ -22,7 +22,7 @@ import { LINKS } from "../lib/links";
|
||||
|
||||
<div class="media-modal-embed-container" data-embed-kind="">
|
||||
<div class="media-modal-embed-placeholder">
|
||||
<a class="media-modal-embed-fallback" target="_blank" rel="noopener noreferrer"></a>
|
||||
<div class="media-modal-embed-fallback-wrap" hidden></div>
|
||||
</div>
|
||||
<iframe
|
||||
class="media-modal-embed"
|
||||
@@ -43,8 +43,6 @@ import { LINKS } from "../lib/links";
|
||||
</div>
|
||||
|
||||
<div class="media-modal-ctas">
|
||||
<a class="cta primary media-modal-cta-follow" target="_blank" rel="me noopener noreferrer"></a>
|
||||
<a class="cta media-modal-cta-view" target="_blank" rel="me noopener noreferrer"></a>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
@@ -58,14 +56,13 @@ import { LINKS } from "../lib/links";
|
||||
const titleEl = dialog.querySelector(".media-modal-title");
|
||||
const embedContainer = dialog.querySelector(".media-modal-embed-container");
|
||||
const embedPlaceholder = dialog.querySelector(".media-modal-embed-placeholder");
|
||||
const embedFallback = dialog.querySelector(".media-modal-embed-fallback");
|
||||
const embedFallbackWrap = dialog.querySelector(".media-modal-embed-fallback-wrap");
|
||||
const iframe = dialog.querySelector(".media-modal-embed");
|
||||
const audio = dialog.querySelector(".media-modal-audio");
|
||||
const descriptionEl = dialog.querySelector(".media-modal-description");
|
||||
const dateEl = dialog.querySelector(".media-modal-date");
|
||||
const viewsEl = dialog.querySelector(".media-modal-views");
|
||||
const followCta = dialog.querySelector(".media-modal-cta-follow");
|
||||
const viewCta = dialog.querySelector(".media-modal-cta-view");
|
||||
const ctasEl = dialog.querySelector(".media-modal-ctas");
|
||||
const closeBtn = dialog.querySelector(".media-modal-close");
|
||||
|
||||
let triggerElement = null;
|
||||
@@ -166,8 +163,8 @@ import { LINKS } from "../lib/links";
|
||||
embedPlaceholder.style.display = "block";
|
||||
embedContainer.dataset.embedKind = "";
|
||||
iframe.style.display = "";
|
||||
embedFallback.style.display = "none";
|
||||
embedFallback.removeAttribute("href");
|
||||
embedFallbackWrap.textContent = "";
|
||||
embedFallbackWrap.hidden = true;
|
||||
audio.pause();
|
||||
audio.removeAttribute("src");
|
||||
audio.style.display = "none";
|
||||
@@ -176,6 +173,8 @@ import { LINKS } from "../lib/links";
|
||||
kickerEl.textContent = "";
|
||||
iframe.removeAttribute("allow");
|
||||
iframe.removeAttribute("height");
|
||||
|
||||
ctasEl.textContent = "";
|
||||
}
|
||||
|
||||
// Close modal
|
||||
@@ -262,8 +261,8 @@ import { LINKS } from "../lib/links";
|
||||
if (embed) {
|
||||
embedContainer.dataset.embedKind = embed.kind;
|
||||
embedPlaceholder.style.display = "block";
|
||||
embedFallback.style.display = "none";
|
||||
embedFallback.removeAttribute("href");
|
||||
embedFallbackWrap.textContent = "";
|
||||
embedFallbackWrap.hidden = true;
|
||||
iframe.style.display = "";
|
||||
|
||||
if (embed.kind === "spotify") {
|
||||
@@ -296,15 +295,22 @@ import { LINKS } from "../lib/links";
|
||||
if (audioUrl) {
|
||||
embedContainer.dataset.embedKind = "audio";
|
||||
embedPlaceholder.style.display = "none";
|
||||
embedFallback.style.display = "none";
|
||||
embedFallbackWrap.textContent = "";
|
||||
embedFallbackWrap.hidden = true;
|
||||
audio.style.display = "block";
|
||||
audio.src = audioUrl;
|
||||
} else {
|
||||
embedContainer.dataset.embedKind = "fallback";
|
||||
embedPlaceholder.style.display = "flex";
|
||||
embedFallback.style.display = "inline-flex";
|
||||
embedFallback.href = url;
|
||||
embedFallback.textContent = "Listen on Spotify";
|
||||
embedFallbackWrap.textContent = "";
|
||||
embedFallbackWrap.hidden = false;
|
||||
const fallbackLink = document.createElement("a");
|
||||
fallbackLink.className = "media-modal-embed-fallback";
|
||||
fallbackLink.target = "_blank";
|
||||
fallbackLink.rel = "noopener noreferrer";
|
||||
fallbackLink.href = url;
|
||||
fallbackLink.textContent = "Listen on Spotify";
|
||||
embedFallbackWrap.appendChild(fallbackLink);
|
||||
audio.style.display = "none";
|
||||
}
|
||||
} else {
|
||||
@@ -329,13 +335,20 @@ import { LINKS } from "../lib/links";
|
||||
utm_campaign: "social-acquisition",
|
||||
utm_content: `${platform}:media_modal`,
|
||||
});
|
||||
followCta.href = followUrl;
|
||||
followCta.textContent = followLabel;
|
||||
followCta.setAttribute("data-umami-event", "cta_click");
|
||||
followCta.setAttribute("data-umami-event-target_id", `modal.cta.${followAction}.${platform}`);
|
||||
followCta.setAttribute("data-umami-event-placement", "media_modal");
|
||||
followCta.setAttribute("data-umami-event-platform", platform);
|
||||
followCta.setAttribute("data-umami-event-target_url", channelUrl);
|
||||
ctasEl.textContent = "";
|
||||
|
||||
const followLink = document.createElement("a");
|
||||
followLink.className = "cta primary media-modal-cta-follow";
|
||||
followLink.target = "_blank";
|
||||
followLink.rel = "me noopener noreferrer";
|
||||
followLink.href = followUrl;
|
||||
followLink.textContent = followLabel;
|
||||
followLink.setAttribute("data-umami-event", "cta_click");
|
||||
followLink.setAttribute("data-umami-event-target_id", `modal.cta.${followAction}.${platform}`);
|
||||
followLink.setAttribute("data-umami-event-placement", "media_modal");
|
||||
followLink.setAttribute("data-umami-event-platform", platform);
|
||||
followLink.setAttribute("data-umami-event-target_url", channelUrl);
|
||||
ctasEl.appendChild(followLink);
|
||||
|
||||
const viewUrl = withUtm(url, {
|
||||
utm_source: "website",
|
||||
@@ -343,13 +356,18 @@ import { LINKS } from "../lib/links";
|
||||
utm_campaign: "social-acquisition",
|
||||
utm_content: `${platform}:media_modal`,
|
||||
});
|
||||
viewCta.href = viewUrl;
|
||||
viewCta.textContent = viewLabel;
|
||||
viewCta.setAttribute("data-umami-event", "cta_click");
|
||||
viewCta.setAttribute("data-umami-event-target_id", `modal.cta.${viewAction}.${platform}`);
|
||||
viewCta.setAttribute("data-umami-event-placement", "media_modal");
|
||||
viewCta.setAttribute("data-umami-event-platform", platform);
|
||||
viewCta.setAttribute("data-umami-event-target_url", url);
|
||||
const viewLink = document.createElement("a");
|
||||
viewLink.className = "cta media-modal-cta-view";
|
||||
viewLink.target = "_blank";
|
||||
viewLink.rel = "me noopener noreferrer";
|
||||
viewLink.href = viewUrl;
|
||||
viewLink.textContent = viewLabel;
|
||||
viewLink.setAttribute("data-umami-event", "cta_click");
|
||||
viewLink.setAttribute("data-umami-event-target_id", `modal.cta.${viewAction}.${platform}`);
|
||||
viewLink.setAttribute("data-umami-event-placement", "media_modal");
|
||||
viewLink.setAttribute("data-umami-event-platform", platform);
|
||||
viewLink.setAttribute("data-umami-event-target_url", url);
|
||||
ctasEl.appendChild(viewLink);
|
||||
|
||||
// Open the dialog
|
||||
dialog.showModal();
|
||||
|
||||
@@ -54,7 +54,15 @@ const elementProps = mode === "modal"
|
||||
<div class="card-media">
|
||||
{imageUrl ? (
|
||||
<div class="img-shimmer-wrap">
|
||||
<img src={imageUrl} alt="" loading="lazy" class="img-loading" />
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt=""
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
width="360"
|
||||
height="180"
|
||||
class="img-loading"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div class="card-placeholder" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import { getPublicConfig } from "../lib/config";
|
||||
import "../styles/global.css";
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
@@ -42,16 +43,9 @@ const assetSuffix = cfg.assetVersion ? `?v=${encodeURIComponent(cfg.assetVersion
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.png" />
|
||||
<link rel="icon" href="/favicon.png" />
|
||||
|
||||
<!-- Display-friendly font (swap to avoid blocking render). -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;800&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="preload" href="/fonts/manrope-latin-400-normal.woff2" as="font" type="font/woff2" crossorigin />
|
||||
<link rel="preload" href="/fonts/manrope-latin-600-normal.woff2" as="font" type="font/woff2" crossorigin />
|
||||
|
||||
<link rel="stylesheet" href={`/styles/global.css${assetSuffix}`} />
|
||||
|
||||
<script is:inline>
|
||||
(() => {
|
||||
const THEME_KEY = "site.theme";
|
||||
|
||||
@@ -3,11 +3,28 @@ import BlogLayout from "../../layouts/BlogLayout.astro";
|
||||
import BlogPostCard from "../../components/BlogPostCard.astro";
|
||||
import { readContentCache } from "../../lib/content/cache";
|
||||
import { wordpressCategories, wordpressPages, wordpressPosts } from "../../lib/content/selectors";
|
||||
import { getPublicConfig } from "../../lib/config";
|
||||
|
||||
const cache = await readContentCache();
|
||||
const categories = wordpressCategories(cache);
|
||||
const posts = wordpressPosts(cache);
|
||||
const pages = wordpressPages(cache);
|
||||
|
||||
const cfg = getPublicConfig();
|
||||
const siteUrl = (cfg.siteUrl || "http://localhost:4321").replace(/\/$/, "");
|
||||
|
||||
const blogJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Blog",
|
||||
name: "SanthoshJ Blog",
|
||||
url: `${siteUrl}/blog`,
|
||||
blogPost: posts.slice(0, 20).map((post) => ({
|
||||
"@type": "BlogPosting",
|
||||
headline: post.title,
|
||||
url: `${siteUrl}/blog/post/${post.slug}`,
|
||||
datePublished: post.publishedAt,
|
||||
})),
|
||||
};
|
||||
---
|
||||
|
||||
<BlogLayout
|
||||
@@ -16,6 +33,7 @@ const pages = wordpressPages(cache);
|
||||
canonicalPath="/blog"
|
||||
categories={categories}
|
||||
>
|
||||
<script type="application/ld+json" set:html={JSON.stringify(blogJsonLd)} />
|
||||
<section class="section">
|
||||
<div class="section-header">
|
||||
<h2>Latest posts</h2>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import BlogLayout from "../../../layouts/BlogLayout.astro";
|
||||
import { readContentCache } from "../../../lib/content/cache";
|
||||
import { wordpressCategories, wordpressPostBySlug, wordpressPosts } from "../../../lib/content/selectors";
|
||||
import { getPublicConfig } from "../../../lib/config";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const cache = await readContentCache();
|
||||
@@ -21,6 +22,32 @@ if (!post) {
|
||||
}
|
||||
|
||||
const metaDescription = (post.excerpt || "").slice(0, 160);
|
||||
const cfg = getPublicConfig();
|
||||
const siteUrl = (cfg.siteUrl || "http://localhost:4321").replace(/\/$/, "");
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
headline: post.title,
|
||||
description: metaDescription || "Blog post",
|
||||
image: post.featuredImageUrl || undefined,
|
||||
datePublished: post.publishedAt,
|
||||
dateModified: post.updatedAt,
|
||||
mainEntityOfPage: {
|
||||
"@type": "WebPage",
|
||||
"@id": `${siteUrl}/blog/post/${post.slug}`,
|
||||
},
|
||||
author: {
|
||||
"@type": "Person",
|
||||
name: "SanthoshJ",
|
||||
url: `${siteUrl}/`,
|
||||
},
|
||||
publisher: {
|
||||
"@type": "Person",
|
||||
name: "SanthoshJ",
|
||||
url: `${siteUrl}/`,
|
||||
},
|
||||
};
|
||||
---
|
||||
|
||||
<BlogLayout
|
||||
@@ -30,6 +57,7 @@ const metaDescription = (post.excerpt || "").slice(0, 160);
|
||||
categories={categories}
|
||||
ogImageUrl={post.featuredImageUrl}
|
||||
>
|
||||
<script type="application/ld+json" set:html={JSON.stringify(jsonLd)} />
|
||||
<section class="section">
|
||||
<div class="section-header">
|
||||
<h2 style="margin: 0;">{post.title}</h2>
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
} from "../lib/content/selectors";
|
||||
import { readFeaturedVideoIds } from "../lib/content/curation";
|
||||
import { LINKS } from "../lib/links";
|
||||
import { getPublicConfig } from "../lib/config";
|
||||
|
||||
const cache = await readContentCache();
|
||||
const featuredIds = await readFeaturedVideoIds();
|
||||
@@ -36,13 +37,35 @@ const options = {
|
||||
};
|
||||
|
||||
const newYorkTime = new Date(cache.generatedAt).toLocaleString('en-US', options);
|
||||
|
||||
const cfg = getPublicConfig();
|
||||
const siteUrl = (cfg.siteUrl || "http://localhost:4321").replace(/\/$/, "");
|
||||
|
||||
const homeJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "WebSite",
|
||||
name: "SanthoshJ",
|
||||
url: `${siteUrl}/`,
|
||||
inLanguage: "en-US",
|
||||
},
|
||||
{
|
||||
"@type": "Person",
|
||||
name: "SanthoshJ",
|
||||
url: `${siteUrl}/`,
|
||||
sameAs: [LINKS.youtubeChannel, LINKS.instagramProfile, LINKS.podcast],
|
||||
},
|
||||
],
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title="SanthoshJ | Tech, streaming, movies, travel"
|
||||
description="SanthoshJ shares tech, gaming streams, movie recommendations, and travel stories—plus the Irregular Mind podcast. Explore the newest videos and episodes."
|
||||
description="SanthoshJ shares tech, gaming streams, movie recommendations, and travel stories-plus the Irregular Mind podcast. Explore the newest videos and episodes."
|
||||
canonicalPath="/"
|
||||
>
|
||||
<script type="application/ld+json" set:html={JSON.stringify(homeJsonLd)} />
|
||||
<section class="hero">
|
||||
<div>
|
||||
<h1>Tech, gaming, movies & travel — videos + podcast by SanthoshJ</h1>
|
||||
|
||||
@@ -4,11 +4,36 @@ import ContentCard from "../components/ContentCard.astro";
|
||||
import MediaModal from "../components/MediaModal.astro";
|
||||
import { readContentCache } from "../lib/content/cache";
|
||||
import { podcastEpisodes } from "../lib/content/selectors";
|
||||
import { getPublicConfig } from "../lib/config";
|
||||
|
||||
const cache = await readContentCache();
|
||||
const episodes = podcastEpisodes(cache).sort(
|
||||
(a, b) => Date.parse(b.publishedAt) - Date.parse(a.publishedAt),
|
||||
);
|
||||
|
||||
const cfg = getPublicConfig();
|
||||
const siteUrl = (cfg.siteUrl || "http://localhost:4321").replace(/\/$/, "");
|
||||
const canonicalUrl = `${siteUrl}/podcast`;
|
||||
|
||||
const podcastJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "CollectionPage",
|
||||
name: "Podcast | Irregular Mind",
|
||||
url: canonicalUrl,
|
||||
mainEntity: {
|
||||
"@type": "ItemList",
|
||||
itemListElement: episodes.slice(0, 20).map((episode, index) => ({
|
||||
"@type": "ListItem",
|
||||
position: index + 1,
|
||||
url: `${siteUrl}/podcast/${encodeURIComponent(episode.id)}`,
|
||||
item: {
|
||||
"@type": "PodcastEpisode",
|
||||
name: episode.title,
|
||||
datePublished: episode.publishedAt,
|
||||
},
|
||||
})),
|
||||
},
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
@@ -16,6 +41,7 @@ const episodes = podcastEpisodes(cache).sort(
|
||||
description="Episodes from the Irregular Mind podcast."
|
||||
canonicalPath="/podcast"
|
||||
>
|
||||
<script type="application/ld+json" set:html={JSON.stringify(podcastJsonLd)} />
|
||||
<section class="section">
|
||||
<div class="section-header">
|
||||
<h2>Irregular Mind</h2>
|
||||
|
||||
@@ -4,11 +4,36 @@ import ContentCard from "../components/ContentCard.astro";
|
||||
import MediaModal from "../components/MediaModal.astro";
|
||||
import { readContentCache } from "../lib/content/cache";
|
||||
import { youtubeVideos } from "../lib/content/selectors";
|
||||
import { getPublicConfig } from "../lib/config";
|
||||
|
||||
const cache = await readContentCache();
|
||||
const videos = youtubeVideos(cache).sort(
|
||||
(a, b) => Date.parse(b.publishedAt) - Date.parse(a.publishedAt),
|
||||
);
|
||||
|
||||
const cfg = getPublicConfig();
|
||||
const siteUrl = (cfg.siteUrl || "http://localhost:4321").replace(/\/$/, "");
|
||||
const canonicalUrl = `${siteUrl}/videos`;
|
||||
|
||||
const videosJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "CollectionPage",
|
||||
name: "Videos | SanthoshJ",
|
||||
url: canonicalUrl,
|
||||
mainEntity: {
|
||||
"@type": "ItemList",
|
||||
itemListElement: videos.slice(0, 20).map((video, index) => ({
|
||||
"@type": "ListItem",
|
||||
position: index + 1,
|
||||
url: `${siteUrl}/videos/${encodeURIComponent(video.id)}`,
|
||||
item: {
|
||||
"@type": "VideoObject",
|
||||
name: video.title,
|
||||
uploadDate: video.publishedAt,
|
||||
},
|
||||
})),
|
||||
},
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
@@ -16,6 +41,7 @@ const videos = youtubeVideos(cache).sort(
|
||||
description="Latest and featured YouTube videos."
|
||||
canonicalPath="/videos"
|
||||
>
|
||||
<script type="application/ld+json" set:html={JSON.stringify(videosJsonLd)} />
|
||||
<section class="section">
|
||||
<div class="section-header">
|
||||
<h2>Videos</h2>
|
||||
|
||||
1244
site/src/styles/global.css
Normal file
1244
site/src/styles/global.css
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user