How I make Strawberry Italian Ice

Summer is hot. I like sweets. I derived my recipe from an ancient older Chicago Tribune article.

Ingredients

  • 1 cup sugar
  • 1 cup water
  • 20 strawberries (substitute a similar volume of your favorite fruit)
  • 6 cups ice cubes

Directions

The first step is to make our fruit sugar mixture:

  1. Dice fruit into small pieces.
  2. Make simple syrup: Mix 1 cup sugar and 1 cup water, boil until sugar is dissolved.
  3. Mix 1 cup of hot simple syrup with diced fruit.
  4. Allow to cool, and refrigerate overnight.

Note: this simple syrup recipe leaves a little extra for other uses.

The second step is to make italian ice:

  1. Pour the fruit and sugar mixture over 6 cups of ice. Blend with a powerful blender until smooth.

You can eat it right away, but it can be a little runny after being in the blender. I put it into a freezer safe container for an hour or two before serving. If frozen overnight, it may need to thaw for a few minutes before serving.

Shortcut

If you have simple syrup already and don't want to wait, simply throw 1 cup of simple syrup, fruit, and 6 cups ice into blender.

Enjoy

Eat it quick.

Scaling the UI in Thunderbird, including messages list et al.

I use a lot of software on a lot of devices. Sometimes the defaults just don't work for me. Thunderbird is a great mail application, but using it on Ubuntu with a high dpi screen, the messages list was tiny.

There is an advanced setting that allows you to scale the UI, but was difficult to find how to actually change it. This old support forum explains how to do it in an older version, and this Super User post gets you close.

The bottom line is that you need to get to the Configuration Editor. to edit

layout.css.devPixelsPerPx

The default value was -1.0, but its a scaling setting that you can dial in to get the exact size you want. For my situation, 2.25 seems to work well, but the change is immediate so you can quickly get a sense of what's going to work for you.

Upgrading this site's Nuxt2 to Nuxt3 and Content Module v2

I often use this site to play with new technology, and as such, it goes through a lot of technical changes. When the site was originally upgraded to Nuxt2, it had already been out for a while and Nuxt3 was in beta stage. So I knew this upgrade was coming. Working on some other projects, I realized I needed a bit better handle on Nuxt3 and decided to jump in.

Using Content v2

Content v2 comes with a bunch of quality of life improvements. The ability to write Vue components that can be used in markdown, with parameters is incredible. I'm using that in a few projects, and hope to leverage it on this site too.

I had a hard time getting things to work, because I didn't read the docs. I started with documentDriven mode enabled to generate sitemap.xml. Since I was porting my Nuxt2/Content1 site, things weren't working. Running the site with npm run dev things seemed fine; however, npm run generate would fail with 404 errors on some content:

Errors prerendering:
  ├─ /api/_content/query/brX4CwCJoQ.1710967419806.json (13ms)
  │ ├── Error: [404] Document not found!
  │ └── Linked from /
  ├─ /api/_content/query/wxmlyJ2dlX.1710967419806.json (13ms)
  │ ├── Error: [404] Document not found!
  │ └── Linked from /blog

It turns out that the default route that gets added with documentDriven: true was conflicting in with my [...slug].vue file in a way that didn't totally break things, but didn't totally work either.

I ended up fixing that by backing out of documentDriven mode and updated my slug:

<script setup lang="ts">
const { path } = useRoute();
const { data: article } = await useAsyncData(`catchall-${path}`, () => {
  return queryContent().where({ _path: { $regex: path } }).findOne();
});
</script>
<template>
  <blog-details v-if="article" :article="article"/>
  <ContentDoc v-else />
</template>

This allows me to use my existing blog-details component to render my articles, but also allows me to fall back to the <ContentDoc /> renderer if needed. The astute observer will see that right now all routes go through the blog-details -- at a future date, if/when I want a different treatment I will update the query to only use it if the route starts with /blog/* and use different component for other paths.

This breaks the @nuxt/sitemap plug-in however, more on that below.

Handling Images

The site is using both @nuxt/image and nuxt-content-assets which allows me to store my images right along side my *.md files in the /content/ path. The docs explain how to make it all work, but I'm including a brief snip of the relevant configuration I needed to make it all work.

// nuxt.config.ts
modules: [
  'nuxt-content-assets',
  '@nuxt/content',
  '@nuxt/image',
  '@nuxtjs/sitemap'
],
//...
image: {
  dir: '.nuxt/content-assets/public'
}

The nuxt-content-assets package requires this component be added to work with @nuxt/image:

// /components/content/ProseImg.vue
<template>
  <nuxt-img />
</template>

Sitemap.xml

With Nuxt Content documentDriven: false the sitemap doesn't generate any content, and the mechanism for automatically generating urls is a bit different in v5+ (for Nuxt3). Putting this kind of code into nuxt.config.ts is an anti-pattern, so support was dropped.

This requires setting up a server route, which can then be referenced in nuxt.config.ts as the source for the sitemap data.

// /server/api/sitemap.ts

import { serverQueryContent } from '#content/server';

export default defineSitemapEventHandler(async (e) => {
  const routes = [];

  const posts = await serverQueryContent(e).find();

  routes.push({
    url: '/',
    changefreq: 'weekly',
    priority: 0.5
  });

  routes.push({
    url: '/blog',
    changefreq: 'weekly',
    priority: 0.75
  });

  posts.map((p) => {
    routes.push({
      loc: p._path,
      lastmod: p.lastMod ? p.lastMod : p.date,
    });
  });

  return routes;
});

With this change to nuxt.config.ts to make it link up:

sitemap: {
  sources: ['/api/sitemap'],
},