mirror of
https://github.com/BradNut/personal-website-sveltekit
synced 2025-09-08 23:20:18 +00:00
chore: update dependencies.
This commit is contained in:
parent
8dd671a867
commit
0c0ba92227
11 changed files with 1175 additions and 795 deletions
32
package.json
32
package.json
|
|
@ -18,9 +18,9 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@playwright/test": "^1.51.1",
|
||||
"@playwright/test": "^1.52.0",
|
||||
"@sveltejs/enhanced-img": "^0.4.4",
|
||||
"@sveltejs/kit": "^2.20.1",
|
||||
"@sveltejs/kit": "^2.20.7",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@unpic/svelte": "^1.0.0",
|
||||
|
|
@ -30,32 +30,32 @@
|
|||
"postcss": "^8.5.3",
|
||||
"postcss-import": "^16.1.0",
|
||||
"postcss-load-config": "^6.0.1",
|
||||
"postcss-preset-env": "^10.1.5",
|
||||
"satori": "^0.12.0",
|
||||
"postcss-preset-env": "^10.1.6",
|
||||
"satori": "^0.12.2",
|
||||
"satori-html": "^0.3.2",
|
||||
"svelte": "^5.23.2",
|
||||
"svelte-check": "^4.1.5",
|
||||
"svelte": "^5.28.2",
|
||||
"svelte-check": "^4.1.6",
|
||||
"svelte-meta-tags": "^4.2.0",
|
||||
"svelte-preprocess": "^6.0.3",
|
||||
"svelte-sequential-preprocessor": "^2.0.2",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.8.2",
|
||||
"typescript": "^5.8.3",
|
||||
"vanilla-lazyload": "^19.1.3",
|
||||
"vite": "^6.2.2",
|
||||
"vite": "^6.3.3",
|
||||
"vite-imagetools": "^7.0.5",
|
||||
"vitest": "^3.0.9"
|
||||
"vitest": "^3.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@resvg/resvg-js": "^2.6.2",
|
||||
"@sveltejs/adapter-node": "^5.2.11",
|
||||
"@vercel/og": "^0.6.4",
|
||||
"bits-ui": "1.3.13",
|
||||
"flexsearch": "^0.8.103",
|
||||
"ioredis": "^5.6.0",
|
||||
"lucide-svelte": "^0.483.0",
|
||||
"@vercel/og": "^0.6.8",
|
||||
"bits-ui": "1.3.19",
|
||||
"flexsearch": "^0.8.158",
|
||||
"ioredis": "^5.6.1",
|
||||
"lucide-svelte": "^0.503.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"scrape-it": "^6.1.3",
|
||||
"sharp": "^0.33.5",
|
||||
"scrape-it": "^6.1.5",
|
||||
"sharp": "^0.34.1",
|
||||
"svelte-local-storage-store": "^0.6.4"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1380
pnpm-lock.yaml
1380
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -1,34 +1,34 @@
|
|||
import SocialImageCard from "$lib/components/socialImageCard.svelte";
|
||||
import { componentToPng } from "$lib/renderImage";
|
||||
import SocialImageCard from '$lib/components/socialImageCard.svelte';
|
||||
import { componentToPng } from '$lib/renderImage';
|
||||
|
||||
const height = 630;
|
||||
const width = 1200;
|
||||
|
||||
/** @type {import('./$types').RequestHandler} */
|
||||
export async function GET({ url }) {
|
||||
try {
|
||||
const faviconImageName = "b_shell_nut_favicon.png";
|
||||
const image = `${new URL(url.origin).href}${faviconImageName}`;
|
||||
const header = url.searchParams.get("header") ?? undefined;
|
||||
const page = url.searchParams.get("page") ?? undefined;
|
||||
const content = url.searchParams.get("content") ?? "";
|
||||
try {
|
||||
const faviconImageName = 'b_shell_nut_favicon.png';
|
||||
const image = `${new URL(url.origin).href}${faviconImageName}`;
|
||||
const header = url.searchParams.get('header') ?? undefined;
|
||||
const page = url.searchParams.get('page') ?? undefined;
|
||||
const content = url.searchParams.get('content') ?? '';
|
||||
|
||||
// @ts-expect-error: Argument of type 'typeof SocialImageCard__SvelteComponent_' is not assignable to parameter of type 'SvelteComponent<any, any, any>'
|
||||
return componentToPng(
|
||||
SocialImageCard,
|
||||
{
|
||||
header,
|
||||
page,
|
||||
content,
|
||||
image,
|
||||
width: `${width}`,
|
||||
height: `${height}`,
|
||||
url: new URL(url.origin).href,
|
||||
},
|
||||
height,
|
||||
width
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
// @ts-expect-error: Argument of type 'typeof SocialImageCard__SvelteComponent_' is not assignable to parameter of type 'SvelteComponent<any, any, any>'
|
||||
return componentToPng(
|
||||
SocialImageCard,
|
||||
{
|
||||
header,
|
||||
page,
|
||||
content,
|
||||
image,
|
||||
width: `${width}`,
|
||||
height: `${height}`,
|
||||
url: new URL(url.origin).href,
|
||||
},
|
||||
height,
|
||||
width,
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,39 +5,39 @@ import { PUBLIC_SITE_URL } from '$env/static/public';
|
|||
import type { PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ url }) => {
|
||||
const baseUrl = new URL(url.origin).href || PUBLIC_SITE_URL || 'https://bradleyshellnut.com';
|
||||
const currentPageUrl = new URL(url.pathname, url.origin).href;
|
||||
const baseUrl = new URL(url.origin).href || PUBLIC_SITE_URL || 'https://bradleyshellnut.com';
|
||||
const currentPageUrl = new URL(url.pathname, url.origin).href;
|
||||
|
||||
const metaTags: MetaTagsProps = Object.freeze({
|
||||
title: 'Portfolio',
|
||||
description: "Bradley Shellnut's Portfolio",
|
||||
openGraph: {
|
||||
title: 'Portfolio',
|
||||
description: "Bradley Shellnut's Portfolio",
|
||||
url: currentPageUrl,
|
||||
siteName: 'Bradley Shellnut Personal Website',
|
||||
type: 'website',
|
||||
locale: 'en_US',
|
||||
images: [
|
||||
{
|
||||
url: `${baseUrl}og?header=Portfolio | bradleyshellnut.com&page=My portfolio of sites I have created.`,
|
||||
alt: 'Bradley Shellnut Portfolio Page',
|
||||
width: 1200,
|
||||
height: 630
|
||||
}
|
||||
]
|
||||
},
|
||||
twitter: {
|
||||
title: 'Portfolio',
|
||||
description: "Bradley Shellnut's Portfolio",
|
||||
card: 'summary_large_image',
|
||||
image: `${baseUrl}og?header=Portfolio | bradleyshellnut.com&page=My portfolio of sites I have created.`,
|
||||
imageAlt: 'Bradley Shellnut Website Logo'
|
||||
},
|
||||
url: currentPageUrl
|
||||
});
|
||||
const metaTags: MetaTagsProps = Object.freeze({
|
||||
title: 'Portfolio',
|
||||
description: "Bradley Shellnut's Portfolio",
|
||||
openGraph: {
|
||||
title: 'Portfolio',
|
||||
description: "Bradley Shellnut's Portfolio",
|
||||
url: currentPageUrl,
|
||||
siteName: 'Bradley Shellnut Personal Website',
|
||||
type: 'website',
|
||||
locale: 'en_US',
|
||||
images: [
|
||||
{
|
||||
url: `${baseUrl}og?header=Portfolio | bradleyshellnut.com&page=My portfolio of sites I have created.`,
|
||||
alt: 'Bradley Shellnut Portfolio Page',
|
||||
width: 1200,
|
||||
height: 630,
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
title: 'Portfolio',
|
||||
description: "Bradley Shellnut's Portfolio",
|
||||
card: 'summary_large_image',
|
||||
image: `${baseUrl}og?header=Portfolio | bradleyshellnut.com&page=My portfolio of sites I have created.`,
|
||||
imageAlt: 'Bradley Shellnut Website Logo',
|
||||
},
|
||||
url: currentPageUrl,
|
||||
});
|
||||
|
||||
return {
|
||||
metaTagsChild: metaTags
|
||||
};
|
||||
return {
|
||||
metaTagsChild: metaTags,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
import shellnutArchitectWebsite from "../../lib/assets/images/portfolio/Mark_Shellnut_Architect.png?enhanced";
|
||||
import oldSite from "../../lib/assets/images/portfolio/Old_Website_Bradley_Shellnut.png?enhanced";
|
||||
import weddingWebsite from "../../lib/assets/images/portfolio/Wedding_Website.png?enhanced";
|
||||
import { gitHubIcon } from "$root/lib/util/logoIcons.svelte";
|
||||
import { gitHubIcon } from "$lib/util/logoIcons.svelte";
|
||||
</script>
|
||||
|
||||
{#snippet links(externalLinks: ExternalLinkType[])}
|
||||
|
|
@ -124,34 +124,43 @@
|
|||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<p>The previous version of my website was written using React and Gatsby which
|
||||
you can view <ExternalLink
|
||||
linkData={{
|
||||
href: "https://wonderful-austin-9f17d2.netlify.app/",
|
||||
ariaLabel: "React and Gatsby Personal Site version",
|
||||
}}
|
||||
textData={{ text: "here.", showIcon: true, location: "left" }}
|
||||
/></p>
|
||||
<p>
|
||||
The previous version of my website was written using React and Gatsby
|
||||
which you can view <ExternalLink
|
||||
linkData={{
|
||||
href: "https://wonderful-austin-9f17d2.netlify.app/",
|
||||
ariaLabel: "React and Gatsby Personal Site version",
|
||||
}}
|
||||
textData={{ text: "here.", showIcon: true, location: "left" }}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
Each iteration brings better code and my previous React version was
|
||||
improved after the suggestions on <ExternalLink
|
||||
linkData={{
|
||||
href: "https://syntax.fm/show/444/syntax-highlight#t=33:19",
|
||||
ariaLabel: "Syntax.fm Podcast Number 444",
|
||||
}}
|
||||
textData={{ text: "Show 444", showIcon: true, location: "left" }}
|
||||
/> of the <ExternalLink
|
||||
linkData={{ href: "https://syntax.fm/", ariaLabel: "Syntax.fm" }}
|
||||
textData={{ text: "Syntax Pocast.", showIcon: true, location: "left" }}
|
||||
/></p>
|
||||
<p>You can view the previous archived version of the site before those
|
||||
changes <ExternalLink
|
||||
textData={{ text: "here.", showIcon: true, location: "left" }}
|
||||
linkData={{
|
||||
href: "https://web.archive.org/web/20210224002046/https://bradleyshellnut.com/",
|
||||
ariaLabel: "Archive before Syntax Podcast",
|
||||
}}
|
||||
/></p>
|
||||
improved after the suggestions on <ExternalLink
|
||||
linkData={{
|
||||
href: "https://syntax.fm/show/444/syntax-highlight#t=33:19",
|
||||
ariaLabel: "Syntax.fm Podcast Number 444",
|
||||
}}
|
||||
textData={{ text: "Show 444", showIcon: true, location: "left" }}
|
||||
/> of the <ExternalLink
|
||||
linkData={{ href: "https://syntax.fm/", ariaLabel: "Syntax.fm" }}
|
||||
textData={{
|
||||
text: "Syntax Pocast.",
|
||||
showIcon: true,
|
||||
location: "left",
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
You can view the previous archived version of the site before those
|
||||
changes <ExternalLink
|
||||
textData={{ text: "here.", showIcon: true, location: "left" }}
|
||||
linkData={{
|
||||
href: "https://web.archive.org/web/20210224002046/https://bradleyshellnut.com/",
|
||||
ariaLabel: "Archive before Syntax Podcast",
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</Portfolio>
|
||||
<Portfolio
|
||||
name="Wedding Website"
|
||||
|
|
@ -169,16 +178,24 @@
|
|||
},
|
||||
]}
|
||||
>
|
||||
<p>The app was initially created for my wedding but what is linked here is a public demo of the application.</p>
|
||||
<p>An application that allows viewing of wedding details and provides the ability to RSVP to the wedding.</p>
|
||||
<p>
|
||||
The app was initially created for my wedding but what is linked here is
|
||||
a public demo of the application.
|
||||
</p>
|
||||
<p>
|
||||
An application that allows viewing of wedding details and provides the
|
||||
ability to RSVP to the wedding.
|
||||
</p>
|
||||
<p>Tech stack:</p>
|
||||
<ul>
|
||||
<li>Next.js 13</li>
|
||||
<li>React 18</li>
|
||||
<li><ExternalLink
|
||||
linkData={{ href: "https://radix-ui.com/", ariaLabel: "Radix UI" }}
|
||||
textData={{ text: "Radix UI", showIcon: true, location: "left" }}
|
||||
/></li>
|
||||
<li>
|
||||
<ExternalLink
|
||||
linkData={{ href: "https://radix-ui.com/", ariaLabel: "Radix UI" }}
|
||||
textData={{ text: "Radix UI", showIcon: true, location: "left" }}
|
||||
/>
|
||||
</li>
|
||||
<li>MongoDB</li>
|
||||
<li>Styled Components</li>
|
||||
<li>Next Iron Session</li>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import type { Picture } from 'vite-imagetools';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { ExternalLinkType } from '$lib/types/externalLinkType';
|
||||
import type { Picture } from "vite-imagetools";
|
||||
import type { Snippet } from "svelte";
|
||||
import type { ExternalLinkType } from "$lib/types/externalLinkType";
|
||||
|
||||
const {
|
||||
links,
|
||||
|
|
@ -10,11 +10,20 @@
|
|||
src,
|
||||
alt,
|
||||
style,
|
||||
fetchPriority = 'auto',
|
||||
loading = 'lazy',
|
||||
children
|
||||
}: { links: Snippet<ExternalLinkType[]>, externalLinks: ExternalLinkType[], name: string; src: string | Picture; alt: string;
|
||||
style: string; fetchPriority?: 'high' | 'low' | 'auto'; loading?: 'lazy' | 'eager', children?: Snippet } = $props();
|
||||
fetchPriority = "auto",
|
||||
loading = "lazy",
|
||||
children,
|
||||
}: {
|
||||
links: Snippet<ExternalLinkType[]>;
|
||||
externalLinks: ExternalLinkType[];
|
||||
name: string;
|
||||
src: string | Picture;
|
||||
alt: string;
|
||||
style: string;
|
||||
fetchPriority?: "high" | "low" | "auto";
|
||||
loading?: "lazy" | "eager";
|
||||
children?: Snippet;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<div class="portfolio">
|
||||
|
|
|
|||
|
|
@ -1,70 +1,147 @@
|
|||
<script lang="ts">
|
||||
import ExternalLink from '$lib/components/ExternalLink.svelte';
|
||||
import ExternalLink from "$lib/components/ExternalLink.svelte";
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<h1>Privacy</h1>
|
||||
<p>
|
||||
Long story short, I believe everyone should know who has your personal
|
||||
data, how it is being collected/stored, and what it is being used for.
|
||||
Long story short, I believe everyone should know who has your personal data,
|
||||
how it is being collected/stored, and what it is being used for.
|
||||
</p>
|
||||
<p>
|
||||
However, it is ultimately up to each person to determine how much data
|
||||
they are willing to give to any business/entity.
|
||||
However, it is ultimately up to each person to determine how much data they
|
||||
are willing to give to any business/entity.
|
||||
</p>
|
||||
<p>
|
||||
For the sake of transparency I am using <ExternalLink textData={{ text: "Umami Analytics", showIcon: true, location: "left" }} linkData={{ href: "https://umami.is", ariaLabel: "Umami Analytics" }} /> to anonymously track visits to my site. You can completely block this if you want by either using an AdBlocker like <ExternalLink textData={{ text: "uBlock Origin", showIcon: true, location: "left" }} linkData={{ href: "https://ublockorigin.com/", ariaLabel: "uBlock Origin" }} />. Sending "Do Not Track" requests in your browser is supported but not overall it is not recommended to turn this on since it can be used to fingerprint you on the web.</p>
|
||||
For the sake of transparency I am using <ExternalLink
|
||||
textData={{ text: "Umami Analytics", showIcon: true, location: "left" }}
|
||||
linkData={{ href: "https://umami.is", ariaLabel: "Umami Analytics" }}
|
||||
/> to anonymously track visits to my site. You can completely block this if you
|
||||
want by either using an AdBlocker like <ExternalLink
|
||||
textData={{ text: "uBlock Origin", showIcon: true, location: "left" }}
|
||||
linkData={{
|
||||
href: "https://ublockorigin.com/",
|
||||
ariaLabel: "uBlock Origin",
|
||||
}}
|
||||
/>. Sending "Do Not Track" requests in your browser is supported but not
|
||||
overall it is not recommended to turn this on since it can be used to
|
||||
fingerprint you on the web.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Useful Resources</h2>
|
||||
<p>
|
||||
Here are a few sites/lists of privacy oriented software for you to
|
||||
check out:
|
||||
Here are a few sites/lists of privacy oriented software for you to check
|
||||
out:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<ExternalLink linkData={{ href: "https://www.eff.org/privacybadger", ariaLabel: "Privacy Badger" }} textData={{ text: "Privacy Badger", showIcon: true, location: "left" }} />
|
||||
<ExternalLink textData={{ text: "Awesome Privacy", showIcon: true, location: "left" }} linkData={{ href: "https://github.com/Lissy93/awesome-privacy", ariaLabel: "Awesome Privacy" }} />
|
||||
<ExternalLink
|
||||
textData={{ text: "Awesome Privacy", showIcon: true, location: "left" }}
|
||||
linkData={{
|
||||
href: "https://github.com/Lissy93/awesome-privacy",
|
||||
ariaLabel: "Awesome Privacy",
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<ExternalLink linkData={{ href: "https://privacyguides.org/", ariaLabel: "Privacy Guides" }} textData={{ text: "Privacy Guides", showIcon: true, location: "left" }} />
|
||||
<ExternalLink
|
||||
linkData={{
|
||||
href: "https://privacyguides.org/",
|
||||
ariaLabel: "Privacy Guides",
|
||||
}}
|
||||
textData={{ text: "Privacy Guides", showIcon: true, location: "left" }}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<ExternalLink linkData={{ href: "https://ethical.net/resources/", ariaLabel: "Ethical Alternatives" }} textData={{ text: "Ethical Alternatives", showIcon: true, location: "left" }} />
|
||||
<ExternalLink
|
||||
linkData={{
|
||||
href: "https://ethical.net/resources/",
|
||||
ariaLabel: "Ethical Alternatives",
|
||||
}}
|
||||
textData={{
|
||||
text: "Ethical Alternatives",
|
||||
showIcon: true,
|
||||
location: "left",
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Privacy Centric Paid Services I use:</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Article Saving: <ExternalLink textData={{ text: "Wallabag Article Saver", showIcon: true, location: "left" }} linkData={{ href: "https://wallabag.com/", ariaLabel: "Wallabag Article Saver" }} />
|
||||
</li>
|
||||
<li>
|
||||
Anonymous Email Forwarding: <ExternalLink textData={{ text: "SimpleLogin (Now owned by Proton AG)", showIcon: true, location: "left" }} linkData={{ href: "https://simplelogin.io", ariaLabel: "SimpleLogin" }} />
|
||||
</li>
|
||||
<li>
|
||||
Email: <ExternalLink textData={{ text: "ProtonMail", showIcon: true, location: "left" }} linkData={{ href: "https://protonmail.com/", ariaLabel: "ProtonMail" }} />
|
||||
</li>
|
||||
<li>
|
||||
Notes: <ExternalLink textData={{ text: "Joplin Notes", showIcon: true, location: "left" }} linkData={{ href: "https://joplinapp.org/", ariaLabel: "Joplin Notes" }} />
|
||||
</li>
|
||||
<li>
|
||||
VPN: <ExternalLink textData={{ text: "ProtonVPN", showIcon: true, location: "left" }} linkData={{ href: "https://protonvpn.com", ariaLabel: "ProtonVPN" }} />
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Privacy Centric Paid Services I use:</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Article Saving: <ExternalLink
|
||||
textData={{
|
||||
text: "Wallabag Article Saver",
|
||||
showIcon: true,
|
||||
location: "left",
|
||||
}}
|
||||
linkData={{
|
||||
href: "https://wallabag.com/",
|
||||
ariaLabel: "Wallabag Article Saver",
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
Anonymous Email Forwarding: <ExternalLink
|
||||
textData={{
|
||||
text: "SimpleLogin (Now owned by Proton AG)",
|
||||
showIcon: true,
|
||||
location: "left",
|
||||
}}
|
||||
linkData={{ href: "https://simplelogin.io", ariaLabel: "SimpleLogin" }}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
Email: <ExternalLink
|
||||
textData={{ text: "ProtonMail", showIcon: true, location: "left" }}
|
||||
linkData={{ href: "https://protonmail.com/", ariaLabel: "ProtonMail" }}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
Notes: <ExternalLink
|
||||
textData={{ text: "Joplin Notes", showIcon: true, location: "left" }}
|
||||
linkData={{ href: "https://joplinapp.org/", ariaLabel: "Joplin Notes" }}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
VPN: <ExternalLink
|
||||
textData={{ text: "ProtonVPN", showIcon: true, location: "left" }}
|
||||
linkData={{ href: "https://protonvpn.com", ariaLabel: "ProtonVPN" }}
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3>NAS Servers for Self Hosting:</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<ExternalLink textData={{ text: "Synology NAS", showIcon: true, location: "left" }} linkData={{ href: "https://synology.com/", ariaLabel: "Synology NAS" }} />
|
||||
: An easy, not cheap, local solution for Google Services like Drive, Photos, Calendar, other services using Docker, etc. (Yes I should use <ExternalLink textData={{ text: "NextCloud Local Hosting Service", showIcon: true, location: "left" }} linkData={{ href: "https://nextcloud.com/", ariaLabel: "NextCloud Local Hosting Service" }} />...maybe eventually)
|
||||
</li>
|
||||
<li>
|
||||
Custom NAS Server used as a <ExternalLink textData={{ text: "Plex Machine", showIcon: true, location: "left" }} linkData={{ href: "https://www.plex.tv/", ariaLabel: "Plex" }} />
|
||||
</li>
|
||||
</ul>
|
||||
<h3>NAS Servers for Self Hosting:</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<ExternalLink
|
||||
textData={{ text: "Synology NAS", showIcon: true, location: "left" }}
|
||||
linkData={{ href: "https://synology.com/", ariaLabel: "Synology NAS" }}
|
||||
/>
|
||||
: An easy, not cheap, local solution for Google Services like Drive, Photos,
|
||||
Calendar, other services using Docker, etc. (Yes I should use <ExternalLink
|
||||
textData={{
|
||||
text: "NextCloud Local Hosting Service",
|
||||
showIcon: true,
|
||||
location: "left",
|
||||
}}
|
||||
linkData={{
|
||||
href: "https://nextcloud.com/",
|
||||
ariaLabel: "NextCloud Local Hosting Service",
|
||||
}}
|
||||
/>...maybe eventually)
|
||||
</li>
|
||||
<li>
|
||||
Custom NAS Server used as a <ExternalLink
|
||||
textData={{ text: "Plex Machine", showIcon: true, location: "left" }}
|
||||
linkData={{ href: "https://www.plex.tv/", ariaLabel: "Plex" }}
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
|
|
@ -78,4 +155,4 @@ import ExternalLink from '$lib/components/ExternalLink.svelte';
|
|||
list-style-type: square;
|
||||
padding-inline-start: 4rem;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -5,39 +5,39 @@ import { PUBLIC_SITE_URL } from '$env/static/public';
|
|||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load: PageLoad = async ({ url }) => {
|
||||
const baseUrl = new URL(url.origin).href || PUBLIC_SITE_URL || 'https://bradleyshellnut.com';
|
||||
const currentPageUrl = new URL(url.pathname, url.origin).href;
|
||||
const baseUrl = new URL(url.origin).href || PUBLIC_SITE_URL || 'https://bradleyshellnut.com';
|
||||
const currentPageUrl = new URL(url.pathname, url.origin).href;
|
||||
|
||||
const metaTags: MetaTagsProps = Object.freeze({
|
||||
title: 'Privacy Blog',
|
||||
description: 'My thoughts on personal internet privacy.',
|
||||
openGraph: {
|
||||
title: 'Privacy Blog',
|
||||
description: 'My thoughts on personal internet privacy.',
|
||||
url: new URL(url.pathname, url.origin).href,
|
||||
siteName: 'Bradley Shellnut Personal Website',
|
||||
type: 'website',
|
||||
locale: 'en_US',
|
||||
images: [
|
||||
{
|
||||
url: `${baseUrl}og?header=Privacy Blog | bradleyshellnut.com&page=My thoughts on personal internet privacy.`,
|
||||
alt: 'Bradley Shellnut Privacy Blog',
|
||||
width: 1200,
|
||||
height: 630
|
||||
}
|
||||
]
|
||||
},
|
||||
twitter: {
|
||||
title: 'Privacy Blog',
|
||||
description: 'My thoughts on personal internet privacy.',
|
||||
card: 'summary_large_image',
|
||||
image: `${baseUrl}og?header=Privacy Blog | bradleyshellnut.com&page=My thoughts on personal internet privacy.`,
|
||||
imageAlt: 'Bradley Shellnut Website Logo'
|
||||
},
|
||||
url: currentPageUrl
|
||||
});
|
||||
const metaTags: MetaTagsProps = Object.freeze({
|
||||
title: 'Privacy Blog',
|
||||
description: 'My thoughts on personal internet privacy.',
|
||||
openGraph: {
|
||||
title: 'Privacy Blog',
|
||||
description: 'My thoughts on personal internet privacy.',
|
||||
url: new URL(url.pathname, url.origin).href,
|
||||
siteName: 'Bradley Shellnut Personal Website',
|
||||
type: 'website',
|
||||
locale: 'en_US',
|
||||
images: [
|
||||
{
|
||||
url: `${baseUrl}og?header=Privacy Blog | bradleyshellnut.com&page=My thoughts on personal internet privacy.`,
|
||||
alt: 'Bradley Shellnut Privacy Blog',
|
||||
width: 1200,
|
||||
height: 630,
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
title: 'Privacy Blog',
|
||||
description: 'My thoughts on personal internet privacy.',
|
||||
card: 'summary_large_image',
|
||||
image: `${baseUrl}og?header=Privacy Blog | bradleyshellnut.com&page=My thoughts on personal internet privacy.`,
|
||||
imageAlt: 'Bradley Shellnut Website Logo',
|
||||
},
|
||||
url: currentPageUrl,
|
||||
});
|
||||
|
||||
return {
|
||||
metaTagsChild: metaTags
|
||||
};
|
||||
return {
|
||||
metaTagsChild: metaTags,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ const config = {
|
|||
kit: {
|
||||
adapter: adapter(),
|
||||
alias: {
|
||||
$lib: './src/lib',
|
||||
$root: './src'
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"useUnknownInCatchVariables": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler",
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
}
|
||||
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"useUnknownInCatchVariables": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler",
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
}
|
||||
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +1,32 @@
|
|||
import { sveltekit } from "@sveltejs/kit/vite";
|
||||
import { defineConfig } from "vite";
|
||||
import { enhancedImages } from "@sveltejs/enhanced-img";
|
||||
import { imagetools } from "@zerodevx/svelte-img/vite";
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
import { enhancedImages } from '@sveltejs/enhanced-img';
|
||||
import { imagetools } from '@zerodevx/svelte-img/vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
enhancedImages(),
|
||||
sveltekit(),
|
||||
imagetools({
|
||||
// By default, directives are `?width=480;1024;1920&format=avif;webp;jpg`
|
||||
// Now we change it to generate 5 variants instead - `avif/jpg` formats at `640/1280` + LQIP (Now as:run)
|
||||
profiles: {
|
||||
run: new URLSearchParams(
|
||||
"?w=300;480;640;1024;1920&format=avif;webp;jpg&as=run:64"
|
||||
),
|
||||
},
|
||||
}),
|
||||
],
|
||||
esbuild: {
|
||||
target: "es2022",
|
||||
},
|
||||
test: {
|
||||
include: ["src/**/*.{test,spec}.{js,ts}"],
|
||||
mockReset: true,
|
||||
},
|
||||
css: {
|
||||
devSourcemap: true,
|
||||
preprocessorOptions: {
|
||||
postcss: {
|
||||
additionalData: `
|
||||
plugins: [
|
||||
enhancedImages(),
|
||||
sveltekit(),
|
||||
imagetools({
|
||||
// By default, directives are `?width=480;1024;1920&format=avif;webp;jpg`
|
||||
// Now we change it to generate 5 variants instead - `avif/jpg` formats at `640/1280` + LQIP (Now as:run)
|
||||
profiles: {
|
||||
run: new URLSearchParams('?w=300;480;640;1024;1920&format=avif;webp;jpg&as=run:64'),
|
||||
},
|
||||
}),
|
||||
],
|
||||
esbuild: {
|
||||
target: 'es2022',
|
||||
},
|
||||
test: {
|
||||
include: ['src/**/*.{test,spec}.{js,ts}'],
|
||||
mockReset: true,
|
||||
},
|
||||
css: {
|
||||
devSourcemap: true,
|
||||
preprocessorOptions: {
|
||||
postcss: {
|
||||
additionalData: `
|
||||
@custom-media --below_small (width < 400px);
|
||||
@custom-media --below_med (width < 700px);
|
||||
@custom-media --below_large (width < 900px);
|
||||
|
|
@ -39,7 +37,7 @@ export default defineConfig({
|
|||
@custom-media --above_large (width > 900px);
|
||||
@custom-media --above_xlarge (width > 1200px);
|
||||
`,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue