diff --git a/public/subtle-stripes.webp b/public/subtle-stripes.webp
deleted file mode 100644
index 679072a7..00000000
Binary files a/public/subtle-stripes.webp and /dev/null differ
diff --git a/public/zachary-proser.webp b/public/zachary-proser.webp
new file mode 100644
index 00000000..b878b869
Binary files /dev/null and b/public/zachary-proser.webp differ
diff --git a/public/zack.png b/public/zack.png
index cc73ac97..8bd1f6b3 100644
Binary files a/public/zack.png and b/public/zack.png differ
diff --git a/public/zack.webp b/public/zack.webp
deleted file mode 100644
index 724f20cc..00000000
Binary files a/public/zack.webp and /dev/null differ
diff --git a/src/app/api/og/route.tsx b/src/app/api/og/route.tsx
index af08cd6f..bdaadf3b 100644
--- a/src/app/api/og/route.tsx
+++ b/src/app/api/og/route.tsx
@@ -14,11 +14,11 @@ export async function GET(request: NextRequest) {
const image = searchParams.get('image') || searchParams.get('amp;image');
const description = searchParams.get('description') || searchParams.get('amp;description');
- const profileImageData = await fetch(new URL('/public/zack.webp', import.meta.url)).then(
+ const profileImageData = await fetch(new URL('/public/zack.png', import.meta.url)).then(
(res) => res.arrayBuffer(),
);
- const fallBackImageURL = new URL('/public/zack-proser-dev-advocate.webp', import.meta.url);
+ const fallBackImageURL = new URL('/public/zack-proser-dev-advocate.png', import.meta.url);
const ultimateURL = image ? new URL(`${process.env.NEXT_PUBLIC_SITE_URL}${image} `) : fallBackImageURL;
let postImageData;
@@ -36,7 +36,7 @@ export async function GET(request: NextRequest) {
@@ -56,14 +56,18 @@ export async function GET(request: NextRequest) {
-
+
+
{title}
+
{description && (
)
}
-
-
diff --git a/src/app/blog/2023-wins/page.mdx b/src/app/blog/2023-wins/page.mdx
index 2d5d2b3f..36ac400c 100644
--- a/src/app/blog/2023-wins/page.mdx
+++ b/src/app/blog/2023-wins/page.mdx
@@ -3,7 +3,6 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import shipLikeCrazy from '@/images/ship-like-crazy.webp'
-import pausingToReflect from '@/images/pausing-to-reflect.webp'
import a16z2 from '@/images/a16z-2.webp'
import a16z11 from '@/images/a16z-11.webp'
import emailOctopusStats from '@/images/email-octopus-stats.webp'
@@ -18,37 +17,23 @@ import initToWinIt from '@/images/init-to-win-it.webp'
import ConsultingCTA from '@/components/ConsultingCTA'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2024-01-08",
title: "Keep Calm and Ship Like Crazy: My 2023 Wins and Lessons",
description: "I had a lot of growth and success to celebrate professionally in 2023",
image: shipLikeCrazy
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+});
+
+export default (props) =>
---
## Catching a breath
-
+
I want to reflect on what I accomplished last year and what I consider my biggest wins:
diff --git a/src/app/blog/a16z-sf-dec-2023-ai-apps-production/page.mdx b/src/app/blog/a16z-sf-dec-2023-ai-apps-production/page.mdx
index 883c25bc..795516b4 100644
--- a/src/app/blog/a16z-sf-dec-2023-ai-apps-production/page.mdx
+++ b/src/app/blog/a16z-sf-dec-2023-ai-apps-production/page.mdx
@@ -3,6 +3,8 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import { Tweet } from 'react-tweet'
+import { createMetadata } from '@/utils/createMetadata'
+
import a16z1 from '@/images/a16z-1.webp'
import a16z2 from '@/images/a16z-2.webp'
import a16z3 from '@/images/a16z-3.webp'
@@ -15,31 +17,17 @@ import a16z9 from '@/images/a16z-9.webp'
import a16z10 from '@/images/a16z-10.webp'
import a16z11 from '@/images/a16z-11.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-12-6",
- title: "Talk @ a16z: Navigating from Jupyter Notebooks to production",
+ title: "Talk @ a16z: Taking AI applications to Production",
description: "I introduced the new Pinecone AWS Reference Architecture with Pulumi and explained infrastructure as code",
image: a16z1
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+});
+
+
+export default (props) =>
---
diff --git a/src/app/blog/api-cicd-pulumi-github/page.mdx b/src/app/blog/api-cicd-pulumi-github/page.mdx
index f99d49af..c02a868f 100644
--- a/src/app/blog/api-cicd-pulumi-github/page.mdx
+++ b/src/app/blog/api-cicd-pulumi-github/page.mdx
@@ -16,31 +16,17 @@ import pulumiPreview from '@/images/pulumi-pr-preview.webp'
import ConsultingCTA from '@/components/ConsultingCTA'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2024-01-01",
title: "A Blueprint for Modern API Development: Repositories developers want to work on",
description: "Developer delight === project velocity ?",
image: developerDelight
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
diff --git a/src/app/blog/article-react-lambda-pipeline/page.mdx b/src/app/blog/article-react-lambda-pipeline/page.mdx
index d9174710..97160ba0 100644
--- a/src/app/blog/article-react-lambda-pipeline/page.mdx
+++ b/src/app/blog/article-react-lambda-pipeline/page.mdx
@@ -3,35 +3,21 @@ import Image from 'next/image'
import { Button } from '@/components/Button'
import reactLambdaPipeline from '@/images/lambda-ci-cd.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2021-04-05",
title: "How to build a React.js and Lambda app with Git push continuous deployment",
description: "An open-source example repository and technical deep-dive on using AWS SAM, Golang, CodePipeline and CloudFormation to automate continuous delivery.",
href: "https://zackproser.substack.com/p/how-to-build-a-reactjs-and-lambda",
image: reactLambdaPipeline
-}
+})
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
+export default (props) =>
-export default (props) =>
+
-
-
-
+
diff --git a/src/app/blog/autogit-introduction/page.mdx b/src/app/blog/autogit-introduction/page.mdx
index b9ae25d1..cb6169a0 100644
--- a/src/app/blog/autogit-introduction/page.mdx
+++ b/src/app/blog/autogit-introduction/page.mdx
@@ -8,9 +8,9 @@ import autogitStashedChangesGif from '@/images/autogit-stashed-changes.gif'
import Image from 'next/image'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = {
author: "Zachary Proser",
date: "2023-05-15",
title: "Autogit - never forget to pull the latest changes again",
@@ -18,21 +18,7 @@ export const meta = {
image: autogitGif,
}
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+export default (props) =>
Even experienced programmers make mistakes - lately I've been forgetting to git pull on my local repos when working quickly, leading my poor colleague Max to have to Slack me messages like this while we're on pair-coding calls:
diff --git a/src/app/blog/automations-project/page.mdx b/src/app/blog/automations-project/page.mdx
index 5679adf6..84cd0800 100644
--- a/src/app/blog/automations-project/page.mdx
+++ b/src/app/blog/automations-project/page.mdx
@@ -11,31 +11,17 @@ import autopullrequestExample from '@/images/autopullrequest-example.webp'
import Image from 'next/image'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-05-24",
title: "Automations - shell scripts leveraging OpenAI to make your developer workflow buttery smooth and way more fun",
description: "I have open sourced my automations project, which is a collection of shell scripts that automatically handle git operations, provide local code reviews, pull requests, and more!",
image: automationsGif,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
diff --git a/src/app/blog/bitwarden-cli-tokens/page.mdx b/src/app/blog/bitwarden-cli-tokens/page.mdx
index bffdc972..9732c78f 100644
--- a/src/app/blog/bitwarden-cli-tokens/page.mdx
+++ b/src/app/blog/bitwarden-cli-tokens/page.mdx
@@ -1,31 +1,17 @@
import { ArticleLayout } from '@/components/ArticleLayout'
import { Button } from '@/components/Button'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2022-10-27",
title: "How to securely store secrets in BitWarden CLI and load them into your shell when needed",
description: "A tutorial on how to write and use shell functions to fetch your tokens from the BitWarden CLI with one command. ",
href: "https://blog.gruntwork.io/how-to-securely-store-secrets-in-bitwarden-cli-and-load-them-into-your-zsh-shell-when-needed-f12d4d040df"
-}
+})
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
+export default (props) =>
-export default (props) =>
-
-
+
diff --git a/src/app/blog/bubbletea-state-machine/page.mdx b/src/app/blog/bubbletea-state-machine/page.mdx
index a0478140..c04a4d03 100644
--- a/src/app/blog/bubbletea-state-machine/page.mdx
+++ b/src/app/blog/bubbletea-state-machine/page.mdx
@@ -5,31 +5,17 @@ import simpleStepsGif from '@/images/stages.gif'
import elmArchitecture from '@/images/elm-architecture.svg'
import bubbleteaStagesGif from '@/images/bubbletea-stages.gif'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-04-25",
title: "The Bubbletea (TUI) State Machine pattern",
description: "Combining a lightweight state machine plus the Bubbletea charm library leads to a very powerful pattern for tooling that needs to orchestrate slow or expensive steps.",
image: bubbleteaStagesGif,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
+})
-export default (props) =>
+export default (props) =>
## A powerful pattern for CLI's that orchestrate complex deployments or workflows
diff --git a/src/app/blog/building-nuxt-portfolio/page.mdx b/src/app/blog/building-nuxt-portfolio/page.mdx
index 4d3c6757..2c79a99f 100644
--- a/src/app/blog/building-nuxt-portfolio/page.mdx
+++ b/src/app/blog/building-nuxt-portfolio/page.mdx
@@ -1,35 +1,21 @@
import { ArticleLayout } from '@/components/ArticleLayout'
import { Button } from '@/components/Button'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2014-01-01",
title: "Building the ultimate portfolio site with Nuxt.js and Netlify.",
description: "A technical deep dive on building a portfolio site that is beautiful, blazing fast and 100% SEO optimized",
href: "https://itnext.io/building-the-ultimate-portfolio-site-with-nuxt-js-and-netlify-beautiful-blazing-fast-100-seod-102913a60cfd?sk=796ec0cdf5ab4325f66a8dde48df1eff"
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
## Note - this article is pretty old at this point!
-
+
diff --git a/src/app/blog/canyonrunner-html5-game/page.mdx b/src/app/blog/canyonrunner-html5-game/page.mdx
index d5ac1951..9b1694f2 100644
--- a/src/app/blog/canyonrunner-html5-game/page.mdx
+++ b/src/app/blog/canyonrunner-html5-game/page.mdx
@@ -15,31 +15,17 @@ import multipleEndings from '@/images/canyonrunner-screens/CanyonRunner-Two-Diff
import Image from 'next/image'
import Link from 'next/link'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2019-02-28",
title: "CanyonRunner - a complete HTML5 game",
description: "I open sourced my first HTML5 game as a resource for other developers working with Phaser.js or wanting to build their own game",
image: canyonRunnerBlog,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
diff --git a/src/app/blog/catfacts-golang/page.mdx b/src/app/blog/catfacts-golang/page.mdx
index d964b6ec..4450f390 100644
--- a/src/app/blog/catfacts-golang/page.mdx
+++ b/src/app/blog/catfacts-golang/page.mdx
@@ -3,31 +3,18 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import catfactsBlog from '@/images/catfacts-screens/catfacts-blog.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2019-10-20",
title: "CatFacts rewrite in Golang",
description: "A ridiculously over-engineered CatFacts prank written in Golang and deployed via Kubernetes",
image: catfactsBlog
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+
+export default (props) =>
diff --git a/src/app/blog/catfacts/page.mdx b/src/app/blog/catfacts/page.mdx
index 7bf84311..3de264c5 100644
--- a/src/app/blog/catfacts/page.mdx
+++ b/src/app/blog/catfacts/page.mdx
@@ -5,31 +5,17 @@ import Link from 'next/link'
import catfactsBlog from '@/images/catfacts-screens/catfacts-blog.webp'
import catfactsScreenshot from '@/images/catfacts-screens/catfacts.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2018-01-08",
title: "CatFacts in Node.js",
description: "PICK UP THE PHONE - ITS CATFACTS!",
image: catfactsBlog
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
diff --git a/src/app/blog/chatgpt-4-and-codeium-are-my-favorite-stack/page.mdx b/src/app/blog/chatgpt-4-and-codeium-are-my-favorite-stack/page.mdx
index 274329fd..325e4947 100644
--- a/src/app/blog/chatgpt-4-and-codeium-are-my-favorite-stack/page.mdx
+++ b/src/app/blog/chatgpt-4-and-codeium-are-my-favorite-stack/page.mdx
@@ -11,31 +11,18 @@ import aiDirectEnhancement from '@/images/ai-direct-enhancement.webp'
import ConsultingCTA from '@/components/ConsultingCTA'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-10-10',
title: 'ChatGPT4 and Codeium are still my favorite dev assistant stack',
description: 'As of October 10th, 2023, ChatGPT4 and Codeium are still my favorite AI-assisted dev tool stack. Here is why',
image: myFavoriteAIStack
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+
+export default (props) => As of October 10th, 2023, ChatGPT4 and Codeium are all I need to make excellent progress and have fun doing it.
@@ -132,7 +119,6 @@ when to raise its hand to point out something that's going to cause the build to
-
We're not quite there yet, but all of the base ingredients to create this experience are.
Indeed, many different companies both large and small are sprinting full-tilt toward this experience, as I've written about recently, but there's still quite a way to go until these tools present uniformly smooth experiences to their end users:
diff --git a/src/app/blog/chatgpt-4-experiment-ai-development/page.mdx b/src/app/blog/chatgpt-4-experiment-ai-development/page.mdx
index 7b82d46e..ca887ef4 100644
--- a/src/app/blog/chatgpt-4-experiment-ai-development/page.mdx
+++ b/src/app/blog/chatgpt-4-experiment-ai-development/page.mdx
@@ -8,31 +8,18 @@ import pairingSocials from '@/images/chatgpt4-screens/ChatGPT4-pairing-socials.w
import aiSupport from '@/images/ai-support.webp'
import aiSupport2 from '@/images/ai-support-2.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-04-10',
title: 'Can ChatGPT-4 and GitHub Copilot help me produce a more complete side project more quickly?',
description: 'As a Senior Software Engineer, I'm always looking for ways to refine my skills and optimize my workflow. This weekend, I experimented with integrating ChatGPT-4 into my developer toolkit alongside GitHub Copilot, which I've been using for several months. The goal? To see if these AI-powered tools could help me complete a side project more quickly. ',
image: aiSupport2
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+
+export default (props) => Chat GPT-4 pointing out one of my bugs while I work
diff --git a/src/app/blog/codeium-review/page.mdx b/src/app/blog/codeium-review/page.mdx
index b10221f7..f2b920d9 100644
--- a/src/app/blog/codeium-review/page.mdx
+++ b/src/app/blog/codeium-review/page.mdx
@@ -8,31 +8,17 @@ import Link from 'next/link'
import ConsultingCTA from '@/components/ConsultingCTA'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-05-29",
title: "Codeium with Neovim for A.I. powered code-completion: so far so good",
description: "Generally unimpressed with GitHub's Copilot (not Copilot X), I gave the alternative, Codeium a shot.",
image: codeiumExample,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
## Codeium is a GitHub Copilot alternative that I'm trying out
diff --git a/src/app/blog/codeium-vs-chatgpt/page.mdx b/src/app/blog/codeium-vs-chatgpt/page.mdx
index 5f550bde..c4e51b68 100644
--- a/src/app/blog/codeium-vs-chatgpt/page.mdx
+++ b/src/app/blog/codeium-vs-chatgpt/page.mdx
@@ -11,35 +11,22 @@ import projectBasedLearning from '@/images/project-based-learning.webp'
import ConsultingCTA from '@/components/ConsultingCTA'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2024-2-02",
title: "Codeium vs ChatGPT",
description: "What's the difference between Codeium and ChatGPT and which should you use?",
image: codeiumVsChatGPT
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+
+export default (props) =>
---
-
+
Codeium began its life as an AI developer tool that offered code-completion for software developers, and
ChatGPT was originally a general purpose AI language model that could assist with a variety of tasks.
diff --git a/src/app/blog/codium-ai-pinecone-pr-agent/page.mdx b/src/app/blog/codium-ai-pinecone-pr-agent/page.mdx
index fb9b8b5a..60bbabae 100644
--- a/src/app/blog/codium-ai-pinecone-pr-agent/page.mdx
+++ b/src/app/blog/codium-ai-pinecone-pr-agent/page.mdx
@@ -3,39 +3,25 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import OctocatSearch from '@/images/octocat-similar-issues-search.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-09-20",
title: "Making it easier to maintain open-source projects with CodiumAI and Pinecone",
description: "CodiumAI's PR-agent integration leverages Pinecone under the hood to perform semantic search for similar GitHub issues",
href: "https://pinecone.io/blog/codiumai-pinecone-similar-issues",
image: OctocatSearch
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
-
+
This was the fifth article I published while working at Pinecone:
-
+
diff --git a/src/app/blog/comic-strip-long-day/page.mdx b/src/app/blog/comic-strip-long-day/page.mdx
index bb779e13..109537df 100644
--- a/src/app/blog/comic-strip-long-day/page.mdx
+++ b/src/app/blog/comic-strip-long-day/page.mdx
@@ -5,7 +5,7 @@ import RenderNumYearsExperience from '@/components/NumYearsExperience'
import Image from 'next/image'
import Link from 'next/link'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
import comicStrip1 from '@/images/comic-strip-1.webp'
import comicStrip2 from '@/images/comic-strip-2.webp'
@@ -15,29 +15,15 @@ import comicStrip5 from '@/images/comic-strip-5.webp'
import comicStrip6 from '@/images/comic-strip-6.webp'
import comicStrip7 from '@/images/comic-strip-7.webp'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-11-30",
title: "Comic strip: long day at the office",
description: "A wordless comic strip about a typically brutal day at work, that nevertheless has a positive ending",
image: comicStrip4,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
diff --git a/src/app/blog/evolving-web-scraping-pageripper-api/page.mdx b/src/app/blog/evolving-web-scraping-pageripper-api/page.mdx
index 0d7d8910..87608e87 100644
--- a/src/app/blog/evolving-web-scraping-pageripper-api/page.mdx
+++ b/src/app/blog/evolving-web-scraping-pageripper-api/page.mdx
@@ -7,31 +7,17 @@ import serverSideScraping from '@/images/serverside-scraping.webp'
import clientSideScraping from '@/images/clientside-scraping.webp'
import pageripperPuppeteer from '@/images/pageripper-puppeteer.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-12-31",
title: "Evolving web scraping: How Pageripper API handles JavaScript-heavy sites",
description: "Pageripper API uses Puppeteer and headless Chrome under the hood to see the same thing your browser does, even for Single Page Applications (SPAs)",
image: pageripperBot
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
diff --git a/src/app/blog/first-see-if-youve-got-the-bug/page.mdx b/src/app/blog/first-see-if-youve-got-the-bug/page.mdx
index 4e92d409..9ae52628 100644
--- a/src/app/blog/first-see-if-youve-got-the-bug/page.mdx
+++ b/src/app/blog/first-see-if-youve-got-the-bug/page.mdx
@@ -20,33 +20,19 @@ import descentCoverArt from '@/images/descent.webp'
import Image from 'next/image'
import Link from 'next/link'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
import ConsultingCTA from '@/components/ConsultingCTA'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-07-17",
title: "First, find out if you've got the programming bug",
description: "I get this question a lot: how do I get into coding? This is my best advice.",
image: sparkOfLearning,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
diff --git a/src/app/blog/for-zachary/page.mdx b/src/app/blog/for-zachary/page.mdx
index 0abb9ffb..a91471b3 100644
--- a/src/app/blog/for-zachary/page.mdx
+++ b/src/app/blog/for-zachary/page.mdx
@@ -8,33 +8,17 @@ import flashback from '@/images/flashback.webp'
import rewiringMyBrain from '@/images/rewiring-my-brain.webp'
import theLightWasYou from '@/images/the-light-was-you.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-10-15',
title: 'For Zachary',
description: 'There are only two people I am aware of named Zachary Proser, with that exact spelling. This article is only for Zachary Proser.',
image: zacharyLight
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-
-export default (props) =>
+})
+export default (props) =>
There are only two people I am aware of named Zachary Proser, with that exact spelling. This article is only for Zachary Proser, but it is published live on the internet for other reasons.
diff --git a/src/app/blog/ggshield-can-save-you-from-yourself/page.mdx b/src/app/blog/ggshield-can-save-you-from-yourself/page.mdx
index ac186fc3..a3544bd6 100644
--- a/src/app/blog/ggshield-can-save-you-from-yourself/page.mdx
+++ b/src/app/blog/ggshield-can-save-you-from-yourself/page.mdx
@@ -10,31 +10,18 @@ import gitGuardian from '@/images/gitguardian-logo.webp'
import ggShieldFindingASecret from '@/images/ggshield-pre-commit-scan.webp'
import ggShieldPreventingEscape from '@/images/ggshield-preventing-a-secret-from-escaping.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-07-18",
title: "ggshield can save you from yourself. Never accidentally commit secrets again",
description: "Stop yourself from committing a secret to git with ggshield",
image: leakingASecret,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+
+export default (props) => A developer watching the API key they accidentally committed to GitHub migrating throughout the internet - thinking of the Slack messages they're about to have to send...
diff --git a/src/app/blog/git-xargs-software/page.mdx b/src/app/blog/git-xargs-software/page.mdx
index 77e01e2a..06920e2f 100644
--- a/src/app/blog/git-xargs-software/page.mdx
+++ b/src/app/blog/git-xargs-software/page.mdx
@@ -4,31 +4,17 @@ import gitXargsDemo from '@/images/git-xargs-demo.gif'
import gitXargsTable from '@/images/git-xargs-table.webp'
import gitXargsBanner from '@/images/git-xargs-banner.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2021-04-19",
title: "Git-xargs allows you to run commands and scripts against many Github repos simultaneously",
description: "Git-xargs allows you to run commands and scripts against many Github repos simultaneously",
image: gitXargsBanner,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
----
diff --git a/src/app/blog/github-copilot-review/page.mdx b/src/app/blog/github-copilot-review/page.mdx
index ad564a92..6230337b 100644
--- a/src/app/blog/github-copilot-review/page.mdx
+++ b/src/app/blog/github-copilot-review/page.mdx
@@ -6,31 +6,17 @@ import githubCopilot2 from '@/images/github-copilot-review-2.webp'
import ConsultingCTA from '@/components/ConsultingCTA'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-10-07',
title: 'GitHub Copilot review',
description: 'I got Copilot access for free as an active GitHub open-source maintainer, but would I pay for it?',
image: githubCopilot,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) => GitHub Copilot has immense potential, but continues to underwhelm
diff --git a/src/app/blog/glossary-of-tech-phrases/page.mdx b/src/app/blog/glossary-of-tech-phrases/page.mdx
index d7670098..21b21e77 100644
--- a/src/app/blog/glossary-of-tech-phrases/page.mdx
+++ b/src/app/blog/glossary-of-tech-phrases/page.mdx
@@ -7,31 +7,17 @@ import { Newsletter } from '@/components/Newsletter'
import Image from 'next/image'
import Link from 'next/link'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-9-9",
title: "Glossary of tech phrases",
description: "If you're coming from Hacker News, I've learned that I need to spell out at the beginning that this post is partly facetious...",
image: frustration
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
diff --git a/src/app/blog/how-developers-evaluate-ai-coding-tools/page.mdx b/src/app/blog/how-developers-evaluate-ai-coding-tools/page.mdx
index 934328aa..a87153c3 100644
--- a/src/app/blog/how-developers-evaluate-ai-coding-tools/page.mdx
+++ b/src/app/blog/how-developers-evaluate-ai-coding-tools/page.mdx
@@ -4,33 +4,20 @@ import Image from 'next/image'
import hackerEvaluation from '@/images/hacker-evaluation.webp'
import frustratedDeveloper from '@/images/frustrated-developer.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
import ConsultingCTA from '@/components/ConsultingCTA'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-10-07',
title: 'Why your AI dev tool startup is failing with developers',
description: 'These common mistakes are dooming your AI-assisted developer tooling startup to failure. Don\'t make them',
image: hackerEvaluation,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+
+export default (props) => A frustated senior developer trying our your improperly tested dev tool for the first time
diff --git a/src/app/blog/how-i-keep-my-shit-together/page.mdx b/src/app/blog/how-i-keep-my-shit-together/page.mdx
index 3594ede3..2f5cbb95 100644
--- a/src/app/blog/how-i-keep-my-shit-together/page.mdx
+++ b/src/app/blog/how-i-keep-my-shit-together/page.mdx
@@ -19,31 +19,17 @@ import iceBath from '@/images/ice-bath.webp'
import familyWalk from '@/images/family-walk.webp'
import sleepingHacker from '@/images/sleeping-hacker.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-09-30",
title: "How I keep my shit together",
description: "Practices and protocols that keep me humming along, healthy and productive on a given day",
image: keepingItTogether,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
diff --git a/src/app/blog/how-to-generate-images-with-ai/page.mdx b/src/app/blog/how-to-generate-images-with-ai/page.mdx
index 85a3740a..6de06726 100644
--- a/src/app/blog/how-to-generate-images-with-ai/page.mdx
+++ b/src/app/blog/how-to-generate-images-with-ai/page.mdx
@@ -14,33 +14,19 @@ import civitAI from '@/images/civitai.webp'
import whyCreateAIImages from '@/images/why-create-ai-images.webp'
import haterade from '@/images/haterade.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
import ConsultingCTA from '@/components/ConsultingCTA'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-10-14',
title: 'How to generate images with AI',
description: 'I have used StableDiffusion, AUTOMATIC111, DALLE and Discord bots to generate images in every style for blog posts. You can too.',
image: aiImageGeneration,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) => You can generate images using AI for free online through a variety of methods
diff --git a/src/app/blog/how-to-use-jupyter-notebooks/page.mdx b/src/app/blog/how-to-use-jupyter-notebooks/page.mdx
index 489c4017..8cf0f959 100644
--- a/src/app/blog/how-to-use-jupyter-notebooks/page.mdx
+++ b/src/app/blog/how-to-use-jupyter-notebooks/page.mdx
@@ -3,39 +3,25 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import jupyterNotebooks from '@/images/jupyter-notebooks.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-08-23",
title: "How to use Jupyter Notebooks to do Machine Learning and AI tasks",
description: "Jupyter Notebooks are surprisingly easy to get started with - especially when using GitHub and Google Colab",
href: "https://www.pinecone.io/learn/jupyter-notebooks",
image: jupyterNotebooks
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
-
+
This was the third article I published while working at Pinecone:
-
+
diff --git a/src/app/blog/i-am-joining-pinecone-io/page.mdx b/src/app/blog/i-am-joining-pinecone-io/page.mdx
index d53befbb..b97e4035 100644
--- a/src/app/blog/i-am-joining-pinecone-io/page.mdx
+++ b/src/app/blog/i-am-joining-pinecone-io/page.mdx
@@ -9,31 +9,17 @@ import pineconeVectorDatabases from '@/images/pinecone-vector-databases.webp'
import technicalStorytelling from '@/images/technical-storytelling.webp'
import pineconeHiring from '@/images/pinecone-hiring.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-07-23",
title: "I'm joining Pinecone.io as a Staff Developer Advocate!",
description: "Making the pivot from pure software engineering to developer advocacy",
image: joiningPinecone,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
diff --git a/src/app/blog/introducing-pageripper-api/page.mdx b/src/app/blog/introducing-pageripper-api/page.mdx
index 51f8c797..012e66d4 100644
--- a/src/app/blog/introducing-pageripper-api/page.mdx
+++ b/src/app/blog/introducing-pageripper-api/page.mdx
@@ -6,31 +6,17 @@ import pageripperBot from '@/images/pageripper-bot.webp'
import pageripperExtracting from '@/images/pageripper-2.webp'
import pageripperSurfing from '@/images/pageripper-surfing.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-12-28",
title: "Pageripper API: a commercial data-extraction service",
description: "I built an API that extracts data from webpages, even if they're rendered with Javascript. It's defined via Pulumi and deployed on AWS.",
image: pageripperBot
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
+})
-export default (props) =>
+export default (props) =>
---
diff --git a/src/app/blog/javascript-ai/page.mdx b/src/app/blog/javascript-ai/page.mdx
index bda3908b..47e267a2 100644
--- a/src/app/blog/javascript-ai/page.mdx
+++ b/src/app/blog/javascript-ai/page.mdx
@@ -3,39 +3,25 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import JSAI from '@/images/javascript-ai.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-08-11",
title: "AI-powered and built with...JavaScript?",
description: "6 Technology trends position JavaScript developers to reap the rewards of the GenAI boom",
href: "https://www.pinecone.io/learn/javascript-ai",
image: JSAI
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
-
+
This was the second article I published while working at Pinecone:
-
+
diff --git a/src/app/blog/magic-spells/page.mdx b/src/app/blog/magic-spells/page.mdx
index 36ad86d9..25051ccc 100644
--- a/src/app/blog/magic-spells/page.mdx
+++ b/src/app/blog/magic-spells/page.mdx
@@ -23,31 +23,17 @@ import oldDeveloperSpeedAgain from '@/images/old-developer-speed-again.webp'
import veryOldDeveloperSpeed from '@/images/very-old-developer-speed.webp'
import oldEnchantment from '@/images/old-enchantment.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-12-3",
title: "Comic: Magic spells",
description: "A comic strip about casting magic spells",
image: eqVictory
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+});
+
+export default (props) =>
---
diff --git a/src/app/blog/maintaining-this-site-fucking-sucks/page.mdx b/src/app/blog/maintaining-this-site-fucking-sucks/page.mdx
index 6ba27e8c..c15b3b6e 100644
--- a/src/app/blog/maintaining-this-site-fucking-sucks/page.mdx
+++ b/src/app/blog/maintaining-this-site-fucking-sucks/page.mdx
@@ -3,31 +3,17 @@ import Image from 'next/image'
import sisyphus from '@/images/sisyphus-crt-monitor-2.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-04-17",
title: "Maintaining this site fucking sucks",
description: "Join me as I delve into the infuriating, yet enlightening journey of maintaining my own Javascript-heavy website. Learn how battling DNS issues, dependency chaos, niche CSS pre-processors and constant painful upgrades has led to one of the most rewarding projects I've ever created.",
image: sisyphus,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) => A photo of myself working on the previous iteration of this website, which I mostly hand-rolled in order to do things the hard way
diff --git a/src/app/blog/maintaining-this-site-no-longer-fucking-sucks/page.mdx b/src/app/blog/maintaining-this-site-no-longer-fucking-sucks/page.mdx
index 876da7ed..acc4074e 100644
--- a/src/app/blog/maintaining-this-site-no-longer-fucking-sucks/page.mdx
+++ b/src/app/blog/maintaining-this-site-no-longer-fucking-sucks/page.mdx
@@ -8,33 +8,19 @@ import holyComputer from '@/images/holy-computer.webp'
import vercelFunctionsLogging from '@/images/vercel-functions-logging.webp'
import vercelIntegratedAnalytics from '@/images/vercel-integrated-analytics.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
import NextJSErrors from '@/images/next-js-errors.webp'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-04-27",
title: "Maintaining this site no longer fucking sucks",
description: "After re-doing my personal website in next.js and deploying to Vercel, I reflect on how much better the developer experience has become.",
image: holyComputer
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
+})
-export default (props) =>
+export default (props) =>
Ten days ago, I wrote about how maintaining the last generation of my personal portfolio site absolutely FUCKING SUCKED, and
how I knowingly did things the painful way on purpose for years.
@@ -126,7 +112,7 @@ export const meta = {
image: 'optimizer-blog.webp'
}
-export default (props) =>
+export default (props) =>
diff --git a/src/app/blog/my-horrible-career/page.mdx b/src/app/blog/my-horrible-career/page.mdx
index 36145cfa..ad03523c 100644
--- a/src/app/blog/my-horrible-career/page.mdx
+++ b/src/app/blog/my-horrible-career/page.mdx
@@ -4,36 +4,22 @@ import Image from 'next/image'
import Link from 'next/link'
import myHorribleCareer from '@/images/my-horrible-career.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2024-2-06",
title: "My first book credit! My Horrible Career",
description: "What started out as an extended conversation with my mentor about career trajectory became a book!",
image: myHorribleCareer
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
-
+
I've [written before](/blog/why-ive-been-successful) about how one of the best things I ever did for my career was to hire
diff --git a/src/app/blog/office-oracle-overview/page.mdx b/src/app/blog/office-oracle-overview/page.mdx
index 7d61bf48..1e231032 100644
--- a/src/app/blog/office-oracle-overview/page.mdx
+++ b/src/app/blog/office-oracle-overview/page.mdx
@@ -5,33 +5,19 @@ import OfficeOracle from '@/images/michael-scott-oracle.webp'
import OfficeOracle2 from '@/images/michael-scott-oracle-2.webp'
import OfficeOracle3 from '@/images/office-oracle-3.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
import Image from 'next/image'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-07-04",
title: "Office Oracle - a complete AI Chatbot leveraging langchain, Pinecone.io and OpenAI",
description: "I open sourced my next.js AI chatbot and the Jupyter notebooks I used to build it, plus created a video series walking through it all on YouTube",
image: OfficeOracle2,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
diff --git a/src/app/blog/open-sourced-article-optimizer/page.mdx b/src/app/blog/open-sourced-article-optimizer/page.mdx
index 9636d121..d5b30411 100644
--- a/src/app/blog/open-sourced-article-optimizer/page.mdx
+++ b/src/app/blog/open-sourced-article-optimizer/page.mdx
@@ -4,31 +4,18 @@ import HeroImage from './symfony-optimizer-splash.webp'
import ExampleReport from './article-optimizer-example-report.webp'
import OptimizerBlog from '@/images/optimizer-blog.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2022-07-14',
title: 'A powerful and open source content optimizer',
description: 'A full technical deep-dive on my optimizer app and its features',
image: OptimizerBlog,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+
+export default (props) =>
diff --git a/src/app/blog/opengraph-integration/page.mdx b/src/app/blog/opengraph-integration/page.mdx
index bd21c030..81a51f92 100644
--- a/src/app/blog/opengraph-integration/page.mdx
+++ b/src/app/blog/opengraph-integration/page.mdx
@@ -5,31 +5,17 @@ import opengraphFallbackImg from '@/images/og.webp'
import opengraphPreview from '@/images/opengraph-preview.webp'
import opengraphSequence from '@/images/opengraph-sequence.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-08-22",
title: "Opengraph dynamic social images",
description: "I built a custom opengraph image with '@vercel/og' that includes a fallback image for index pages",
image: opengraphFallbackImg
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
+})
-export default (props) =>
+export default (props) =>
- {`${meta.title} - Zachary Proser`}
-
+ {`${metadata.title} - Zachary Proser`}
+
- {meta.title}
-
-
+ {metadata.title}
+
+
@@ -316,8 +302,8 @@ export function ArticleLayout({
-
-
+
+
@@ -337,14 +323,14 @@ export function ArticleLayout({
- {meta.title}
+ {metadata.title}
{children}
@@ -362,5 +348,3 @@ export function ArticleLayout({
## Thanks for reading
If you enjoyed this post or found it helpful in anyway, do me a favor and share the URL somewhere on social media so that you can see my opengraph image in action 🙌😁.
-
-
diff --git a/src/app/blog/page.tsx b/src/app/blog/page.tsx
index d7c31d28..44278fae 100644
--- a/src/app/blog/page.tsx
+++ b/src/app/blog/page.tsx
@@ -1,36 +1,15 @@
-import { type Metadata } from 'next'
-
+import { Metadata } from 'next'
import { SimpleLayout } from '@/components/SimpleLayout'
import { type ArticleWithSlug } from '@/lib/shared-types'
import { getAllArticles } from '@/lib/articles'
import { BlogPostCard } from '@/components/BlogPostCard'
-import { generateOgUrl } from '@/utils/ogUrl'
-
-const data = {
- title: 'Articles',
- description:
- 'All of my technical tutorials, deep-dives, and developer rants'
-
-};
-
-const ogUrl = generateOgUrl(data);
+import { createMetadata } from '@/utils/createMetadata'
-export const metadata: Metadata = {
- openGraph: {
- title: data.title,
- description: data.description,
- url: ogUrl,
- siteName: 'Zack Proser's portfolio',
- images: [
- {
- url: ogUrl,
- }
- ],
- locale: 'en_US',
- type: 'website',
- },
-};
+export const metadata: Metadata = createMetadata({
+ title: "Zachary Proser - Blog",
+ description: "Staff AI engineer - technical writing and development blog"
+});
export default async function ArticlesIndex() {
let articles = await getAllArticles()
diff --git a/src/app/blog/pain-poetry-python/page.mdx b/src/app/blog/pain-poetry-python/page.mdx
index 9f9d96fe..673b67c0 100644
--- a/src/app/blog/pain-poetry-python/page.mdx
+++ b/src/app/blog/pain-poetry-python/page.mdx
@@ -3,39 +3,25 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import PPP from '@/images/pain-poetry-python.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-09-01",
title: "The Pain and Poetry of Python",
description: "A history of package management and virtualenvs in Python and why we migrated the Pinecone Python client to Poetry",
href: "https://pinecone.io/blog/pain-poetry-python",
image: PPP
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
-
+
This was the fourth article I published while working at Pinecone:
-
+
diff --git a/src/app/blog/pinecone-reference-architecture-launch/page.mdx b/src/app/blog/pinecone-reference-architecture-launch/page.mdx
index b571183e..97ef09a4 100644
--- a/src/app/blog/pinecone-reference-architecture-launch/page.mdx
+++ b/src/app/blog/pinecone-reference-architecture-launch/page.mdx
@@ -3,41 +3,27 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import pineconeRefArch from '@/images/pinecone-refarch-logo.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-11-27",
title: "Announcing the Pinecone AWS Reference Architecture in Pulumi",
description: "Deploy production-ready systems using Pinecone in minutes with the AWS Reference Architecture",
href: "https://pinecone.io/blog/aws-reference-architecture",
image: pineconeRefArch
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
-
+
I built Pinecone's first AWS Reference Architecture using Pulumi.
This is the sixth article I wrote while working at Pinecone:
-
+
diff --git a/src/app/blog/pinecone-reference-architecture-scaling/page.mdx b/src/app/blog/pinecone-reference-architecture-scaling/page.mdx
index 3a900f17..748bc23c 100644
--- a/src/app/blog/pinecone-reference-architecture-scaling/page.mdx
+++ b/src/app/blog/pinecone-reference-architecture-scaling/page.mdx
@@ -3,42 +3,26 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import pineconeRefArch from '@/images/pinecone-refarch-logo.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2024-1-23",
title: "Testing Pinecone Serverless at Scale with the AWS Reference Architecture",
description: "A step-by-step walkthrough on how to generate arbitrary system load and flex Pinecone Serverless",
href: "https://www.pinecone.io/learn/scaling-pinecone-serverless/",
image: pineconeRefArch
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
-
+
In this tutorial, I walk readers through how the Pinecone AWS Reference Architecture's autoscaling policies work, and how to
use the tools provided in the repository to generate test records to flex the system under load.
This is the eigth article I wrote while working at Pinecone:
-
-
-
+
diff --git a/src/app/blog/pinecone-reference-architecture-technical-walkthrough/page.mdx b/src/app/blog/pinecone-reference-architecture-technical-walkthrough/page.mdx
index cdc7a8c6..bc074492 100644
--- a/src/app/blog/pinecone-reference-architecture-technical-walkthrough/page.mdx
+++ b/src/app/blog/pinecone-reference-architecture-technical-walkthrough/page.mdx
@@ -3,41 +3,27 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import pineconeRefArch from '@/images/pinecone-ref-arch-blueprint.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-11-27",
title: "Pinecone AWS Reference Architecture Technical Walkthrough",
description: "An examination of the Reference Architecture components and functionality",
href: "https://pinecone.io/learn/aws-reference-architecture",
image: pineconeRefArch
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
-
+
I built Pinecone's first AWS Reference Architecture using Pulumi.
This is the seventh article I wrote while working at Pinecone:
-
+
diff --git a/src/app/blog/programmer-emotions/page.mdx b/src/app/blog/programmer-emotions/page.mdx
index 2fee6f9a..da489f1d 100644
--- a/src/app/blog/programmer-emotions/page.mdx
+++ b/src/app/blog/programmer-emotions/page.mdx
@@ -7,31 +7,17 @@ import { Newsletter } from '@/components/Newsletter'
import Image from 'next/image'
import Link from 'next/link'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-9-11",
title: "Programmer emotions",
description: "Programmers are people, and this is how I feel when...",
image: aHackerMeditatingOnAMatInAPImage
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
diff --git a/src/app/blog/quake-in-fargate/page.mdx b/src/app/blog/quake-in-fargate/page.mdx
index 99dd318a..5c79c1e0 100644
--- a/src/app/blog/quake-in-fargate/page.mdx
+++ b/src/app/blog/quake-in-fargate/page.mdx
@@ -4,39 +4,26 @@ import Link from 'next/link'
import Image from 'next/image'
import quakeInFargate from '@/images/quake-in-fargate.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2022-04-15",
title: "How to Run a Quake 3 Arena Server in an AWS ECS Fargate Task",
description: "A tutorial, along with working Terraform code and Dockerfile, that you can use to deploy and operate your own Quake 3 server in an ECS task.",
href: "https://medium.com/@zackproser/how-to-run-a-quake-server-in-an-aws-fargate-task-aac75c3ab81f",
image: quakeInFargate
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+
+export default (props) =>
---
-
+
- {meta.description}
+ {metadata.description}
-
+
diff --git a/src/app/blog/retrieval-augmented-generation/page.mdx b/src/app/blog/retrieval-augmented-generation/page.mdx
index 26c844fd..b899de6f 100644
--- a/src/app/blog/retrieval-augmented-generation/page.mdx
+++ b/src/app/blog/retrieval-augmented-generation/page.mdx
@@ -3,40 +3,26 @@ import { Button } from '@/components/Button'
import Image from 'next/image'
import RAG from '@/images/retrieval-augmented-generation.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-08-04",
title: "Retrieval Augmented Generation (RAG)",
description: "How to reduce hallucinations in your Generative AI applications",
href: "https://www.pinecone.io/learn/retrieval-augmented-generation",
image: RAG
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
---
-
+
This was the first article I published while working at Pinecone:
-
+
diff --git a/src/app/blog/run-your-own-tech-blog/page.mdx b/src/app/blog/run-your-own-tech-blog/page.mdx
index 26096747..6b1f3261 100644
--- a/src/app/blog/run-your-own-tech-blog/page.mdx
+++ b/src/app/blog/run-your-own-tech-blog/page.mdx
@@ -12,33 +12,19 @@ import bloggingWebPerformance from '@/images/blogging-web-performance.webp'
import bloggingGetsFaster from '@/images/blogging-gets-faster.webp'
import bloggingWaving from '@/images/blogging-waving.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
import ConsultingCTA from '@/components/ConsultingCTA'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-10-18',
title: 'Run your own tech blog',
description: 'Control your own destiny, build your personal brand, and master web technologies by running your own tech blog.',
image: bloggingPeacefully,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) => Blogging is a very worthwhile hobby, especially if you're trying to grow your tech career. Here are some ways I've recently benefited from this blog:
diff --git a/src/app/blog/teatutor-deepdive/page.mdx b/src/app/blog/teatutor-deepdive/page.mdx
index 942e55c6..6ac7d172 100644
--- a/src/app/blog/teatutor-deepdive/page.mdx
+++ b/src/app/blog/teatutor-deepdive/page.mdx
@@ -3,31 +3,17 @@ import Image from 'next/image'
import teatutorLogo from '@/images/teatutor-logo.webp'
import bubbleViewportExample from '@/images/bubble-viewport-example.gif'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2022-10-21",
title: "Teatutor Deep Dive",
description: "Teatutor is a Golang CLI leveraging the Bubbletea Terminal User Interface (TUI) library from Charm.sh. It can be served over an SSH connection.",
image: teatutorLogo,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
+})
-export default (props) =>
+export default (props) =>
diff --git a/src/app/blog/terminal-velocity-overview/page.mdx b/src/app/blog/terminal-velocity-overview/page.mdx
index 6518ef93..76f040fd 100644
--- a/src/app/blog/terminal-velocity-overview/page.mdx
+++ b/src/app/blog/terminal-velocity-overview/page.mdx
@@ -8,31 +8,17 @@ import neotreeDemo from '@/images/neotree.gif'
import ripgrepDemo from '@/images/ripgrep.gif'
import symbolOutlineDemo from '@/images/symboloutline.gif'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2022-04-27",
title: "Terminal velocity - how to get faster as a developer ",
description: "I obssess a decent amount over my own developer productivity and my customized tmux, neovim and awesome window manager linux setup, and now I pass my best learnings on to you",
image: myCustomDevSetup
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
*"You could be the greatest architect in the world, but that won't matter much if it takes you forever to type everything into your computer."* [**Hugo Posca**](https://www.linkedin.com/in/hugoposca/)
diff --git a/src/app/blog/testing-code-on-windows/page.mdx b/src/app/blog/testing-code-on-windows/page.mdx
index 9006c5bb..8a3cca05 100644
--- a/src/app/blog/testing-code-on-windows/page.mdx
+++ b/src/app/blog/testing-code-on-windows/page.mdx
@@ -2,34 +2,20 @@ import { ArticleLayout } from '@/components/ArticleLayout'
import { Button } from '@/components/Button'
import wikka from '@/images/wikka.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2022-07-05",
title: "Writing code on Mac or Linux but testing on Windows with hot-reloading",
description: "As a developer, I often want to test my code on Windows, but don't have a Windows box handy. This tutorial demonstrates how to use Infrastructure as Code (IaC) to make provisioning Windows test instances easier. In this post, I also provide a working Packer template and Terraform configuration to deploy your own Windows test instance, as well as instructions for mounting a local folder over RDP.",
href: "https://blog.gruntwork.io/how-to-write-code-on-mac-or-linux-but-test-on-windows-with-hot-reloading-b218de5383d1",
image: wikka,
-}
+})
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+export default (props) =>
---
-
+
diff --git a/src/app/blog/top-ai-dev-tools-bugs/page.mdx b/src/app/blog/top-ai-dev-tools-bugs/page.mdx
index dc818c49..bf0c9f2a 100644
--- a/src/app/blog/top-ai-dev-tools-bugs/page.mdx
+++ b/src/app/blog/top-ai-dev-tools-bugs/page.mdx
@@ -8,33 +8,19 @@ import agentForgettingPrompting from '@/images/agent-forgetting-its-prompting.we
import yourAIDevToolSucks from '@/images/your-ai-dev-tool-sucks.webp'
import hackerQuitingYourCrappyTool from '@/images/hacker-quitting-your-crappy-tool.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
import ConsultingCTA from '@/components/ConsultingCTA'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-10-09',
title: 'The top bugs all AI developer tools are suffering from',
description: 'I have evaluated everything from ChatGPT to CoPilot to Codeium to Cursor, to Sourcegraph Cody to CodiumAI. All suffer from the same bugs',
image: hackerEvaluation,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) => A confused hacker trying to figure out why the AI-assisted IDE Cursor just broke his entire file by inlining its generated code in the wrong place
diff --git a/src/app/blog/wash-three-walls-with-one-bucket/page.mdx b/src/app/blog/wash-three-walls-with-one-bucket/page.mdx
index eb26e7a2..1d5d2d4c 100644
--- a/src/app/blog/wash-three-walls-with-one-bucket/page.mdx
+++ b/src/app/blog/wash-three-walls-with-one-bucket/page.mdx
@@ -11,31 +11,17 @@ import releaseYourWork from '@/images/release-your-work.webp'
import bullshit from '@/images/bullshit.webp'
import ConsultingCTA from '@/components/ConsultingCTA'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-10-25',
title: 'Wash three walls with one bucket',
description: 'Design your side projects, blog posts and even your fun experiments to triangulate multiple learning paths simultaneously. Then, use them to build out your portfolio.',
image: washThreeWallsWithOneBucket,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) => Without much more work, you can ensure your side projects are not only expanding your knowledge, but also expanding your portfolio of hire-able skills.
diff --git a/src/app/blog/why-ive-been-successful/page.mdx b/src/app/blog/why-ive-been-successful/page.mdx
index 5d3e4173..2f94bc8a 100644
--- a/src/app/blog/why-ive-been-successful/page.mdx
+++ b/src/app/blog/why-ive-been-successful/page.mdx
@@ -3,32 +3,17 @@ import Image from 'next/image'
import gruntworkPromotions from '@/images/gruntwork-promotions.webp'
import layeredLearningPhases from '@/images/successful/layered-learning-phases.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-03-20',
title: "Why I've been successful lately, and what I'm planning to do about it",
description: "In the past 3 years, I've been promoted 3 times. I reflect on the habits and activities that helped me improve the most. ",
image: gruntworkPromotions,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+export default (props) =>
For the past 3 years, I've been working at [Gruntwork](https://gruntwork.io), a DevOps startup that accelerates your launch into AWS by giving you best-practice architectures defined in Terraform, and standing them up in your accounts in about a day.
diff --git a/src/app/blog/wisdomseeker/page.mdx b/src/app/blog/wisdomseeker/page.mdx
index 37250a9a..d53a3e86 100644
--- a/src/app/blog/wisdomseeker/page.mdx
+++ b/src/app/blog/wisdomseeker/page.mdx
@@ -4,31 +4,18 @@ import wisdomseekerHome from '@/images/wisdomseeker-screens/wisdomseeker-home.we
import wisdomseekerSuccess from '@/images/wisdomseeker-screens/wisdomseeker-success.webp'
import wisdomseekerLoop from '@/images/wisdomseeker-screens/wisdomseeker-loop.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2011-09-02',
title: 'Wisdomseeker',
description: 'A wikipedia crawling application',
image: wisdomseekerHome
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+
+export default (props) =>
diff --git a/src/app/blog/working-with-circleci/page.mdx b/src/app/blog/working-with-circleci/page.mdx
index 76759591..5e8bcc01 100644
--- a/src/app/blog/working-with-circleci/page.mdx
+++ b/src/app/blog/working-with-circleci/page.mdx
@@ -1,29 +1,15 @@
import { ArticleLayout } from '@/components/ArticleLayout'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2022-07-14',
title: 'How to work with CircleCI more effectively',
description: 'Pro tips for working with CircleCI configurations',
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>
## Overview
At [Gruntwork](https://gruntwork.io), we use CircleCI as the continuous integration tool for the vast majority of our repositories. This article shares a couple of tips and tricks I've figured out along the way for more easily working with CircleCI locally, since the test cycles in the cloud can be pretty long, depending on what you're using CircleCI for.
diff --git a/src/app/blog/you-get-to-keep-the-neural-connections/page.mdx b/src/app/blog/you-get-to-keep-the-neural-connections/page.mdx
index 57a9c66f..6bd7c851 100644
--- a/src/app/blog/you-get-to-keep-the-neural-connections/page.mdx
+++ b/src/app/blog/you-get-to-keep-the-neural-connections/page.mdx
@@ -7,33 +7,19 @@ import shelvingADistributedSystem from '@/images/shelving-a-distributed-system.w
import puttingTheRefArchDown from '@/images/putting-the-ref-arch-down.webp'
import yourExperienceComesWithYou from '@/images/your-experience-comes-with-you.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
import ConsultingCTA from '@/components/ConsultingCTA'
-export const meta = {
+export const metadata = createMetadata({
author: 'Zachary Proser',
date: '2023-10-14',
title: 'You get to keep the neural connections',
description: 'Going the extra mile only to be unrewarded by your company feels like a personal slight and a waste of your time. It is not.',
image: puttingTheRefArchDown,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) => Going the extra mile only to be unrewarded by your company feels like a personal slight and a waste of your time. It is not.
diff --git a/src/app/blog/yubikey-sudo-git-signing/page.mdx b/src/app/blog/yubikey-sudo-git-signing/page.mdx
index 6ffa201a..901d2099 100644
--- a/src/app/blog/yubikey-sudo-git-signing/page.mdx
+++ b/src/app/blog/yubikey-sudo-git-signing/page.mdx
@@ -11,31 +11,18 @@ import keyboardCamera from '@/images/keyboard-camera.webp'
import keyboardCameraCloseup from '@/images/keyboard-cam-closeup.webp'
import gitCommitSigningSequence from '@/images/git-commit-signing-yubikey-sequence.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-05-07",
title: "Passwordless sudo and verified GitHub commit signing with Yubikey - a pair-coder's dream",
description: "If you're like me, you can't type your complex password correctly when your entire team is staring at you on a pair call. And now, you no longer have to.",
image: stressedTyping,
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+
+export default (props) =>
If you're like me - you can't type your complex password correctly when your entire team is staring at you on a pair coding call.
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index cb7caff9..1e4e3b88 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -13,19 +13,25 @@ import '@/styles/global.css'
import Script from 'next/script'
-export const metadata: Metadata = {
- title: {
- template: '%s - Zachary Proser',
- default:
- 'Zachary Proser - Open-source hacker, writer, and life-long learner',
- },
- description:
- 'I’m Zachary, a staff developer advocate at Pinecone.io where we build a high-scale vector database which is critcal infrastructure for the AI-boom',
- alternates: {
- types: {
- 'application/rss+xml': `${process.env.NEXT_PUBLIC_SITE_URL}/feed.xml`,
+type Props = {
+ params: { id: string }
+ searchParams: { [key: string]: string | string[] | undefined }
+}
+
+export async function generateMetadata({ params }: Props) {
+ return {
+ title: {
+ template: '%s - AI Engineer',
+ default: 'Zachary Proser - Full-stack AI engineer'
},
- },
+ description: 'I build and advise on generative AI applications and pipelines',
+ alternates: {
+ types: {
+ 'application/rss+xml': `${process.env.NEXT_PUBLIC_SITE_URL}/feed.xml`,
+ },
+ },
+
+ }
}
export default function RootLayout({
diff --git a/src/app/videos/building-ai-chatbot-langchain-pinecone/page.mdx b/src/app/videos/building-ai-chatbot-langchain-pinecone/page.mdx
index 91478933..9c42e558 100644
--- a/src/app/videos/building-ai-chatbot-langchain-pinecone/page.mdx
+++ b/src/app/videos/building-ai-chatbot-langchain-pinecone/page.mdx
@@ -2,31 +2,17 @@ import { ArticleLayout } from '@/components/ArticleLayout'
import aiChatbot from '@/images/building-an-ai-chatbot.webp'
-import { generateOgUrl } from '@/utils/ogUrl'
+import { createMetadata } from '@/utils/createMetadata'
-export const meta = {
+export const metadata = createMetadata({
author: "Zachary Proser",
date: "2023-06-30",
title: "Building an AI chatbot with langchain, Pinecone.io, Jupyter notebooks and Vercel",
description: "How I built an Office chatbot that can answer any question about the office",
image: aiChatbot
-}
-
-export const metadata = {
- openGraph: {
- title: meta.title,
- description: meta.description,
- url: "${process.env.NEXT_PUBLIC_SITE_URL}",
- siteName: "Zack Proser portfolio",
- images: [
- {
- url: `${generateOgUrl(meta)}`,
- }
- ]
- }
-}
-
-export default (props) =>
+})
+
+export default (props) =>