Building with LLMs - Part 2
By Me on 2025-01-18
Code Snippets and Favicons
With the meat and potatoes of the website done, I started to think about the details. One thing I wanted to do was to add a favicon to the website, preferably something that at least vaguely resembled a Llama. Given my lack of artistic skills I wanted to use an AI to generate it.
Another detail that bother me was the code snippets. In the first building post, I added a small snippet of code to show what Claude was able to generate. I used a simple
<pre></pre>tag to show the code, but this did not look very good. Given that there are many blogs that use code snippets I was confident that v0 would have a solution for this.
Code Snippets
I reused the existing conversation with v0 to ask it to generate a code snippet component.
I'll create a component for displaying code snippets in blog articles with syntax highlighting and user-friendly handling of longer lines. We'll use the popular `prism-react-renderer` library for syntax highlighting and implement a horizontal scrolling mechanism for longer lines.
Let's create this component and then show how to use it in a blog post:
Now, let me explain the components and how to use them:
- This component uses `prism-react-renderer` for syntax highlighting.
- It supports displaying a filename above the code block.
- Line numbers are included for easy reference.
- A copy button is provided in the top-right corner for easy copying of the entire code snippet.
- Long lines will trigger a horizontal scroll within the code block, maintaining the layout of the page.
- The component is styled to be visually appealing and consistent with the overall design.
1import React from 'react'2import Highlight, { defaultProps, Language } from 'prism-react-renderer'3import theme from 'prism-react-renderer/themes/nightOwl'4import { Button } from "@/components/ui/button"5import { Card } from "@/components/ui/card"6import { Copy } from 'lucide-react'78interface CodeSnippetProps {9 code: string10 language: Language11 filename?: string12}1314export function CodeSnippet({ code, language, filename }: CodeSnippetProps) {15 const [copied, setCopied] = React.useState(false)1617 const copyToClipboard = () => {18 navigator.clipboard.writeText(code)19 setCopied(true)20 setTimeout(() => setCopied(false), 2000)21 }2223 return (24 <Card className="my-6 overflow-hidden">25 {filename && (26 <div className="bg-slate-800 text-slate-200 px-4 py-2 text-sm font-mono border-b border-slate-700">27 {filename}28 </div>29 )}30 <div className="relative">31 <Highlight {...defaultProps} theme={theme} code={code} language={language}>32 {({ className, style, tokens, getLineProps, getTokenProps }) => (33 <pre className={`${className} p-4 overflow-x-auto`} style={style}>34 {tokens.map((line, i) => (35 <div key={i} {...getLineProps({ line, key: i })}>36 <span className="inline-block w-8 text-right mr-4 text-slate-500 select-none">37 {i + 1}38 </span>39 {line.map((token, key) => (40 <span key={key} {...getTokenProps({ token, key })} />41 ))}42 </div>43 ))}44 </pre>45 )}46 </Highlight>47 <Button48 variant="outline"49 size="sm"50 className="absolute top-2 right-2 bg-slate-700 text-slate-200 hover:bg-slate-600"51 onClick={copyToClipboard}52 >53 {copied ? 'Copied!' : <Copy className="h-4 w-4" />}54 </Button>55 </div>56 </Card>57 )58}
This component provides a professional and user-friendly way to display code snippets in your blog posts. It's particularly useful for technical tutorials, programming guides, or any post that needs to showcase code examples.
The design is responsive and should work well on both desktop and mobile devices. The horizontal scrolling for long lines ensures that your page layout isn't broken by extremely long lines of code.
This looked pretty good so I installed the latest version of `prism-react-renderer`, copied the component to my local project, and ran into a few issues.

I instinctively started to dive in the code to figure out what the error was before catching myself and letting Claude do the work.
For the code present, we get this error:
```
Cannot find module 'prism-react-renderer/themes/nightOwl' or its corresponding type declarations.
```
How can I resolve this? If you propose a fix, please make it concise.
The error occurs because the import path for the theme has changed in newer versions of prism-react-renderer. Let's update the imports:
1import React from 'react'2import { Highlight } from 'prism-react-renderer'3import { nightOwl } from 'prism-react-renderer/themes'
This was a step in the right direction, but in the end I had to do a little manual digging to find that I should just import the theme directly in the latest version. I suspect that these kind of errors are very common with generated code as they tend to have been trained on older code and/or documentation.
However, I was able to get the code snippet working with very little effort and it looks pretty good. Better than what I would have come up with myself. It also included a copy button which works, so I'm willing to overlook the small problems with the library version.

Favicon
With the code snippet working, I was ready to move on to the favicon. As I had used ChatGPT before for generating some images I thought I would start there for my favicon.
Here's a minimalist and playful design of a llama's head that could work as a favicon for your website, "llamateur." It's optimized for small-scale use, focusing on clarity and recognizability. Let me know if you'd like any adjustments!

Apart from the blemish on the llama's head, I though it was a pretty good favicon. I tried to get it to generate it as a vector image, but it complained that it was not able to do the vectorisation. After some pleading I got it to generated a simplified SVG design based on the description of the original image.
Considering how it was complaining about the vectorisation, I was expecting a completely different image. I was surprised that it was able to generate something that looked so close to the original. Sadly it also included the blemish. I tried asking ChatGPT to remove it from the original image, but the best it could do was give me directions on how to do it in photo editing software.
When I tried to get it to regenrate the same image it instead came up with something completely different.

Can't fault it for trying, it gave the same prompt to DALL-E yet the result was something else entirely. For a while I considered keeping this image but in the end it just didn't really speak to me. I liked the pixel arty idea though so I tried again with a different prompt.
Here is a pixel art version of the llama's head with a slight angle to add some character and personality. Let me know if you'd like any further adjustments or additional styles!

I was pretty happy with this image. It is simple yet recognisable and I like the pixelated style. I find it funny that it's approximating pixel art with a non-pixelated technique. I suppose the larger canvas size helps hiding imperfections in the generated image.
Regardless of the technicalities, I am happy with the result as it's infinitely better than what I would have come up with!
Inspiration and Copyright
Generating these images was a fun experiment but it got me thinking about the inspiration and 'legitimacy' of AI images as an expression of art. A lot of people consider AI images to be lesser art than traditional art where a human artist did more of the work, but where we draw these lines is not always clear.
Given that humans are also constantly inspired by other humans, taking in their art and generating their own based on this inspiration, why are AI generated images considered lesser art?
I suppose it's similar to AI in programming; it's can be a great tool to assist a developer and help speed up their workflow, but it's probably not a replacement.
To me it also feels similar to electronic music. In its infancy it was considered lesser art than traditional music, but now it's a legitimate form of music in its own right. After all, it's just another tool we can employ to generate sound just like our first analog instruments were.
It's an exiting development though and I enjoy the possibilities it opens up for me as a person without drawing or painting skills.