feat: turned blog into a mini app ๐Ÿ˜Ž 8d83900f
Steve ยท 2025-04-25 12:09 10 file(s) ยท +57 โˆ’46
public/.well-known/farcaster.json (added) +18 โˆ’0
1 +
{
2 +
  "accountAssociation": {
3 +
    "header": "eyJmaWQiOjYwMjMsInR5cGUiOiJjdXN0b2R5Iiwia2V5IjoiMHg0NTYxMzExNjFmODNDN0Q3ZkRBMTViMzJhNWY3QzIxRkQ0RTI3RTk2In0",
4 +
    "payload": "eyJkb21haW4iOiJzdGV2ZWR5bGFuLmRldiJ9",
5 +
    "signature": "MHgzNjRkMTc4NDUzYzk1MjY3ZmRiNjBmOTYwMmM2M2VjOGI4M2RiYzIxOTdkNWQ1NGQ3N2RkYTRmZjllMjA4YWZmNDljYTFlN2U5NGFkN2UxOWNjNzBlM2UzMzIyNDhkZDNiNzg5Y2MyMDIwYWVkNTExNzYzMmUxNTNmOTlmZDE3YTFi"
6 +
  },
7 +
  "frame": {
8 +
    "version": "1",
9 +
    "name": "stevedylan.dev",
10 +
    "iconUrl": "https://stevedylan.dev/icon.png",
11 +
    "homeUrl": "https://stevedylan.dev",
12 +
    "imageUrl": "https://stevedylan.dev/image.png",
13 +
    "buttonTitle": "Read Blog",
14 +
    "splashImageUrl": "https://stevedylan.dev/splash.png",
15 +
    "splashBackgroundColor": "#000000",
16 +
    "webhookUrl": "https://webhooks.pingem.xyz/f/0adv8"
17 +
  }
18 +
}
public/icon.png (added) +0 โˆ’0

Binary file โ€” no preview.

public/image.png (added) +0 โˆ’0

Binary file โ€” no preview.

public/og.png (added) +0 โˆ’0

Binary file โ€” no preview.

public/splash.png (added) +0 โˆ’0

Binary file โ€” no preview.

src/components/BaseHead.astro +22 โˆ’1
14 14
	ogImage ? ogImage : "/social-card.png",
15 15
	Astro.url,
16 16
).href;
17 +
const fcImage = new URL(
18 +
	ogImage ? ogImage : "/image.png",
19 +
	Astro.url,
20 +
).href;
21 +
22 +
const fcData = JSON.stringify({
23 +
  version: "next",
24 +
  imageUrl: fcImage,
25 +
  button: {
26 +
    title: "Read Blog",
27 +
    action: {
28 +
      type: "launch_frame",
29 +
      name: "Read Blog",
30 +
      url: canonicalURL,
31 +
      splashImageUrl: "https://stevedylan.dev/splash.png",
32 +
      splashBackgroundColor: "#000000"
33 +
    }
34 +
  }
35 +
})
17 36
---
18 37
19 38
<meta charset="utf-8" />
34 53
<meta name="author" content={siteConfig.author} />
35 54
36 55
<!-- Theme Colour -->
37 -
<meta name="theme-color" content={siteConfig.themeColorLight} />
56 +
<meta name="theme-color" content="#000000" />
38 57
39 58
<!-- Open Graph / Facebook -->
40 59
<meta property="og:type" content={articleDate ? "article" : "website"} />
64 83
65 84
<!-- RSS auto-discovery -->
66 85
<link rel="alternate" type="application/rss+xml" title={siteConfig.title} href="/rss.xml" />
86 +
87 +
<meta name="fc:frame" content={fcData} />
67 88
68 89
<link
69 90
  rel="preload"
src/components/layout/Footer.astro +12 โˆ’0
34 34
35 35
	</nav>
36 36
</footer>
37 +
38 +
<script type="module">
39 +
    import { sdk } from 'https://esm.sh/@farcaster/frame-sdk';
40 +
    window.onload = async () => {
41 +
      try {
42 +
        await sdk.actions.ready();
43 +
        await sdk.actions.addFrame();
44 +
      } catch (error) {
45 +
        console.error(error);
46 +
      }
47 +
    };
48 +
</script>
src/layouts/Base.astro +2 โˆ’36
6 6
import SkipLink from "@/components/SkipLink";
7 7
import siteConfig from "@/site-config";
8 8
import { ViewTransitions } from "astro:transitions";
9 -
import { Umami } from "astro-analytics";
10 9
11 10
interface Props {
12 11
	meta: SiteMeta;
19 18
20 19
<html lang={siteConfig.lang}>
21 20
	<head>
22 -
      <meta name="apple-mobile-web-app-capable" content="yes">
23 -
      <meta name="theme-color" content="#000000" />
21 +
    <meta name="apple-mobile-web-app-capable" content="yes">
22 +
    <meta name="theme-color" content="#000000" />
24 23
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
25 24
		<!-- Google tag (gtag.js) -->
26 25
		<BaseHead title={title} description={description} ogImage={ogImage} articleDate={articleDate} />
27 26
		<script defer src="https://cloud.umami.is/script.js" data-website-id="6951e531-a667-495e-b045-4f7dbe062446"></script>
28 -
		<!-- <script define:vars={{ siteConfig }}>
29 -
			const root = document.documentElement;
30 -
			const colorThemeMetaTag = document.querySelector("meta[name='theme-color']");
31 -
32 -
			// get user preference of dark mode, 1st local storage, 2nd browser
33 -
			function getThemePreference() {
34 -
				if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) {
35 -
					return localStorage.getItem("theme");
36 -
				}
37 -
				return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "dark";
38 -
			}
39 -
40 -
			const isDark = getThemePreference() === "dark";
41 -
42 -
			// watch document element class attribute and update user preference when it changes.
43 -
			const observer = new MutationObserver(() => {
44 -
				const rootIsDark = root.classList.contains("dark");
45 -
				// set the meta attribute
46 -
				colorThemeMetaTag.setAttribute(
47 -
					"content",
48 -
					siteConfig[rootIsDark ? "themeColorDark" : "themeColorLight"]
49 -
				);
50 -
				// store user preference
51 -
				if (typeof localStorage !== "undefined") {
52 -
					localStorage.setItem("theme", rootIsDark ? "dark" : "dark");
53 -
				}
54 -
			});
55 -
			observer.observe(root, { attributeFilter: ["class"] });
56 -
57 -
			// initailse root class attribute
58 -
			root.classList.toggle("dark", isDark);
59 -
60 -
		</script> -->
61 27
		<ViewTransitions fallback="swap" />
62 28
	</head>
63 29
	<body>
src/pages/guestbook.astro +2 โˆ’3
1 1
---
2 2
import DecryptingHeader from "@/components/DecryptingHeader";
3 3
import PageLayout from "@/layouts/Base";
4 -
import GuestbookFeed from "src/components/GuestbookFeed";
4 +
//import GuestbookFeed from "src/components/GuestbookFeed";
5 5
6 6
const meta = {
7 7
	title: "Guestbook",
12 12
  <div class="space-y-6">
13 13
  <div class="flex flex-col gap-2 mb-6">
14 14
    <DecryptingHeader text="Guestbook" className="title mb-6" />
15 -
    <p>Welcome to my little digital guestbook! I built this using PGlite, Railway, Clerk, and <a href="https://pinata.cloud" class="style-link" target="_blank" rel="noreferrer">Pinata</a>, and you can <a href="/posts/building-a-guestbook-with-pglite-clerk-and-pinata" class="style-link">read about it here</a>. Login with your Github account to leave a message!</p>
15 +
    <p>๐Ÿšง Under Construction ๐Ÿšง</p>
16 16
    </div>
17 -
    <GuestbookFeed API_URL={import.meta.env.PUBLIC_API_URL} client:only="react" />
18 17
  </div>
19 18
</PageLayout>
src/pages/index.astro +1 โˆ’6
23 23
				target="_blank"
24 24
				rel="noopener noreferrer"
25 25
				class="style-link">Orbiter</a
26 -
			>, a simple yet open take on static site hosting. Take a look around and be sure to <a
27 -
				class="style-link"
28 -
				href="/guestbook"
29 -
				data-astro-reload>sign my guestbook</a
30 -
			>!
31 -
		</p>
26 +
			>, a simple yet open take on static site hosting.</p>
32 27
		<SocialList />
33 28
		<p>Or anywhere with my handle <span class="text-accent">@stevedylandev</span></p>
34 29
	</section>