<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/assets/css/rss-feed-v1.xsl" type="text/xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="https://www.simoncox.com/eleventy/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>11ty from SimonCox.com</title>
    <link>https://www.simoncox.com/eleventy/</link>
    <atom:link href="https://www.simoncox.com/eleventy/feed-11ty.xml" rel="self" type="application/rss+xml" />
    <description>Simon Cox&#39;s 11ty feed</description>
    <language>en</language>
    <item>
      <title>Alternate main heading and title in 11ty templates</title>
      <link>https://www.simoncox.com/short-articles/2026-01-17-alternate-main-heading-and-title-in-11ty-templates/</link>
      <description>&lt;h2 id=&quot;11ty-templates-set-up&quot; tabindex=&quot;-1&quot;&gt;11ty templates set up&lt;/h2&gt;
&lt;p&gt;In my 11ty templates I generally use the same content for the title and the h1 tags. In the frontmatter I always have a title field as the title tag is actually the only required html tag in a html document, did you know that? So it makes sense to have the title tag as a requirement in my frontmatter.&lt;/p&gt;
&lt;p&gt;With the h1 headings you can have as many a you like, technically, but I think this can be confusing to both humans and machines when trying to understand a page&#39;s content. The argument has long been that if you have a list of articles you can use the h1 tag for the articles title in that list.&lt;/p&gt;
&lt;p&gt;My reply to that is that a page with a list of articles should have the article titles as h2s and only one h1 at the top of the page to let the user know what is on the page.&lt;/p&gt;
&lt;h2 id=&quot;seo-practicalities-for-title-and-headings&quot; tabindex=&quot;-1&quot;&gt;SEO practicalities for title and headings&lt;/h2&gt;
&lt;p&gt;There is absolutely nothing wrong with having the same title and h1 on a page as far as SEO goes and this is often the easiest to set up as you just repeat the frontmatter title as the h1.&lt;/p&gt;
&lt;p&gt;Yes it is potentially not optimal, as having differing titles and h1&#39;s can cover more ground. This still will not mean overnight success and stardom for most sites. It could tip the balance in your favour in some cases though.&lt;/p&gt;
&lt;h2 id=&quot;11ty-templates-title-set-up&quot; tabindex=&quot;-1&quot;&gt;11ty templates title set up&lt;/h2&gt;
&lt;p&gt;Here is the title tag in my base template for the site:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;title&amp;gt;{{ title }} | Simon Cox&amp;lt;/title&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This picks up the title data from the front matter and adds a pipe and Simon Cox to the end of it for the title. That&#39;s not best practice if you are concerned about title length in the search engine results pages - though that&#39;s becoming less of an issue these days for other reasons - so you shoudl consider if you need your brand on the end of your titles or not.&lt;/p&gt;
&lt;p&gt;Here is my article template for the title and the h1:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;h1&amp;gt;{{ title }}&amp;lt;/h1&amp;gt;
	{{ content | safe }}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This picks up the title frontmatter data and inserts it into the h1 tag and then the rest of the content I have in the markdown file follows.&lt;/p&gt;
&lt;h2 id=&quot;optimising-the-h1-for-seo&quot; tabindex=&quot;-1&quot;&gt;Optimising the h1 for seo&lt;/h2&gt;
&lt;p&gt;So having said that it doesn&#39;t matter if the title and the h1 are the same, there are indeed occasions where I don&#39;t want exactly the same title and h1 content. My favoured way of approaching this is to add h1 content in the frontmatter, usually the row after the title so that I can see what&#39;s going on when I return to the page to fix typos and rewrite the content as I realise my writing can be rubbish at times (like exactly now, to be extra meta about it).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
---
title: Alternate main heading and title in 11ty templates 
h1: Having a different title and h1 text using templating in 11ty
---

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have set up a conditional in the 11ty article template - note that I use nunjucks for my templates:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;h1&amp;gt;{% if h1 %}{{h1}}{% else %}{{ title }}{% endif %}&amp;lt;/h1&amp;gt;
	{{ content | safe }}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If there is a h1 frontmatter data entry then it will be input into the h1 tag. If there isn&#39;t one then the template defaults to using the title - simple and easy to manage.&lt;/p&gt;
&lt;p&gt;This way if I want to add a different h1 then I can add it to the frontmatter, build and deploy.&lt;/p&gt;
&lt;p&gt;If you look at the source code of this page you will find that the title and h1 are indeed different!&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Sat, 17 Jan 2026 00:00:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2026-01-17-alternate-main-heading-and-title-in-11ty-templates/</guid>
    </item>
    <item>
      <title>Creating a modular approach to json schema in an eleventy website</title>
      <link>https://www.simoncox.com/post/2025-10-28-creating-a-modular-approach-to-json-schema-in-an-eleventy-website/</link>
      <description>&lt;p&gt;Having enjoyed  &lt;a href=&quot;https://11tymeetup.dev/events/ep-25-structured-data-and-deploying-11ty/&quot;&gt;Kaj Kandler’s presentation at the 25th 11ty meetup July 2025&lt;/a&gt; I wanted a modular and automated way to add json schema to my personal website so built a set of templates and some simple logic.&lt;/p&gt;
&lt;h2 id=&quot;schema-files-structure-in-11ty&quot; tabindex=&quot;-1&quot;&gt;Schema files Structure in 11ty&lt;/h2&gt;
&lt;p&gt;I have created a schema directory in the includes directory and keep all the files associated with this in there.&lt;/p&gt;
&lt;p&gt;This has a main schema.njk file that is pulled into my base template which I use for all pages.
&lt;code&gt;src/_includes/base.njk&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In the base.njk I have this following include after the pages footer and before the body closes.
&lt;code&gt;{%- include &amp;quot;schema/schema.njk&amp;quot; -%}&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-schema.njk-file&quot; tabindex=&quot;-1&quot;&gt;The schema.njk file&lt;/h2&gt;
&lt;p&gt;The file that pulls the schema all together is&lt;/p&gt;
&lt;p&gt;The full schema file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{%- set graph = [] %}



{# Include SiteNavigationElement #}

{%- set sitenavSchema %}{%- include &amp;quot;schema/SiteNavigationElement.njk&amp;quot; %}{%- endset %}



{# Include base fragments #}

{%- set websiteSchema %}{%- include &amp;quot;schema/website.njk&amp;quot; %}{%- endset %}

{%- set personSchema %}{%- include &amp;quot;schema/person.njk&amp;quot; %}{%- endset %}

{%- set organizationSchema %}{%- include &amp;quot;schema/organization.njk&amp;quot; %}{%- endset %}

{%- set webpageSchema %}{%- include &amp;quot;schema/webpage.njk&amp;quot; %}{%- endset %}

{%- set graph = graph.concat([sitenavSchema,websiteSchema, personSchema, organizationSchema, webpageSchema]) %}

	

{# Conditionally include article or blogpost schemas #}

{%- if page.url.startsWith(&amp;quot;/post/&amp;quot;) %}

{%- set articleSchema %}{%- include &amp;quot;schema/article.njk&amp;quot; %}{%- endset %}

{%- set graph = graph.concat([articleSchema]) %}

{%- elif page.url.startsWith(&amp;quot;/short-articles/&amp;quot;) %}

{%- set blogpostSchema %}{%- include &amp;quot;schema/blogpost.njk&amp;quot; %}{%- endset %}

{%- set graph = graph.concat([blogpostSchema]) %}

{%- endif %}

	

{# CollectionPage for /post/, /short-articles/, or /narrow-gauge-modelling/ list pages #}

{%- if page.url == &amp;quot;/post/&amp;quot; %}

{%- set collectionPostSchema %}{%- include &amp;quot;schema/collection-post.njk&amp;quot; %}{%- endset %}

{%- set graph = graph.concat([collectionPostSchema]) %}

{%- elif page.url == &amp;quot;/short-articles/&amp;quot; %}

{%- set collectionShortsSchema %}{%- include &amp;quot;schema/collection-shorts.njk&amp;quot; %}{%- endset %}

{%- set graph = graph.concat([collectionShortsSchema]) %}

{%- elif page.url == &amp;quot;/narrow-gauge-modelling/&amp;quot; %}

{%- set collectionNGMSchema %}{%- include &amp;quot;schema/collection-ngm.njk&amp;quot; %}{%- endset %}

{%- set graph = graph.concat([collectionNGMSchema]) %}

{%- endif %}

	

{# Breadcrumb #}

{%- set breadcrumbSchema %}{%- include &amp;quot;schema/breadcrumb.njk&amp;quot; %}{%- endset %}

{%- set graph = graph.concat([breadcrumbSchema]) %}

	

&amp;lt;script type=&amp;quot;application/ld+json&amp;quot;&amp;gt;

{

&amp;quot;@context&amp;quot;: &amp;quot;https://schema.org&amp;quot;,

&amp;quot;@graph&amp;quot;: [

{{ graph | join(&amp;quot;,&#92;n&amp;quot;) | safe }}

]

}

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;initial-set-up&quot; tabindex=&quot;-1&quot;&gt;Initial set up&lt;/h3&gt;
&lt;p&gt;The file starts with an initial set up&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{%- set graph = [] %}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates an empty array called graph that will hold all the schema objects.&lt;/p&gt;
&lt;h3 id=&quot;including-base-schema-components&quot; tabindex=&quot;-1&quot;&gt;Including Base Schema Components&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;{# Include SiteNavigationElement #}
{%- set sitenavSchema %}{%- include &amp;quot;schema/SiteNavigationElement.njk&amp;quot; %}{%- endset %}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This pattern (repeated for multiple schemas) does three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;{%- set sitenavSchema %}...{%- endset %} captures the output of the included template into a variable&lt;/li&gt;
&lt;li&gt;{%- include &amp;quot;schema/SiteNavigationElement.njk&amp;quot; %} includes the contents of an external template file&lt;/li&gt;
&lt;li&gt;The - in  {%-  removes whitespace before/after the tag for cleaner output&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The same pattern is then repeated for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;websiteSchema - Website information&lt;/li&gt;
&lt;li&gt;personSchema - Person/author information&lt;/li&gt;
&lt;li&gt;organizationSchema - Organization/company information&lt;/li&gt;
&lt;li&gt;webpageSchema - Basic webpage information&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;{%- set graph = graph.concat([sitenavSchema,websiteSchema, personSchema, organizationSchema, webpageSchema]) %}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This adds all the base schemas to the graph array.&lt;/p&gt;
&lt;h3 id=&quot;conditional-article%2Fblog-post-schemas&quot; tabindex=&quot;-1&quot;&gt;Conditional Article/Blog Post Schemas&lt;/h3&gt;
&lt;p&gt;Then I start setting up schemas for types of page. All my article pages are in the post directory so anything in there will need the article schema.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{%- if page.url.startsWith(&amp;quot;/post/&amp;quot;) %}
  {%- set articleSchema %}{%- include &amp;quot;schema/article.njk&amp;quot; %}{%- endset %}
  {%- set graph = graph.concat([articleSchema]) %}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and for the Shorticles in short-articles i decided to use a blog schema instead of article.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{%- elif page.url.startsWith(&amp;quot;/short-articles/&amp;quot;) %}
  {%- set blogpostSchema %}{%- include &amp;quot;schema/blogpost.njk&amp;quot; %}{%- endset %}
  {%- set graph = graph.concat([blogpostSchema]) %}
{%- endif %}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;collection-page-schemas&quot; tabindex=&quot;-1&quot;&gt;Collection Page Schemas&lt;/h3&gt;
&lt;p&gt;For the top level collection pages of lists - such as the articles list and shorticles list pages I have set a collections schema:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{%- if page.url == &amp;quot;/post/&amp;quot; %}
  {%- set collectionPostSchema %}{%- include &amp;quot;schema/collection-post.njk&amp;quot; %}{%- endset %}
  {%- set graph = graph.concat([collectionPostSchema]) %}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These conditions check for exact URL matches to collection/listing pages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/post/ - Main posts listing page&lt;/li&gt;
&lt;li&gt;/short-articles/ - Short articles listing page&lt;/li&gt;
&lt;li&gt;/narrow-gauge-modelling/ - A specific category listing page&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each gets its own collection schema added to the graph.&lt;/p&gt;
&lt;h3 id=&quot;breadcrumb-schema&quot; tabindex=&quot;-1&quot;&gt;Breadcrumb Schema&lt;/h3&gt;
&lt;p&gt;Breadcrumb schema is a tricky one to fathom and the logic is in the breadcrumb.njk file&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{%- set breadcrumbSchema %}{%- include &amp;quot;schema/breadcrumb.njk&amp;quot; %}{%- endset %}
{%- set graph = graph.concat([breadcrumbSchema]) %}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This adds breadcrumb navigation schema to every page.&lt;/p&gt;
&lt;h3 id=&quot;final-json-ld-output&quot; tabindex=&quot;-1&quot;&gt;Final JSON-LD Output&lt;/h3&gt;
&lt;p&gt;Finally it pulls together the elements into a JSON-LD script&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script type=&amp;quot;application/ld+json&amp;quot;&amp;gt;
{
  &amp;quot;@context&amp;quot;: &amp;quot;https://schema.org&amp;quot;,
  &amp;quot;@graph&amp;quot;: [
    {{ graph | join(&amp;quot;,&#92;n&amp;quot;) | safe }}
  ]
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Creates a script tag with type=&amp;quot;application/ld+json&amp;quot; (tells search engines this is structured data)&lt;/li&gt;
&lt;li&gt;Sets the Schema.org context&lt;/li&gt;
&lt;li&gt;Creates a @graph array containing all the collected schemas&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{{ graph | join(&amp;quot;,&#92;n&amp;quot;) | safe }}&lt;/code&gt; joins all array elements with commas and newlines, and marks it as safe HTML (won&#39;t be escaped)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The result is a single script tag containing all relevant structured data for the current page, helping search engines understand the content and potentially enabling rich snippets in search results.&lt;/p&gt;
&lt;h2 id=&quot;individual-schema-files&quot; tabindex=&quot;-1&quot;&gt;Individual Schema files&lt;/h2&gt;
&lt;p&gt;The individual schema types have their own file in:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/_includes/schema/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which contains these files&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;article.njk
blogpost.njk
breadcrumb.njk
collection-post.njk
collection-shorts.njk
contactpage.njk
copyright.njk
faqpage.njk
imageobject.njk
organisation.njk
person.njk
schema.njk – the main file
webpage.njk
website.njk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each of these files created the schema JSON so more can be added as you require. I have listed the code for a couple below to give you the general idea of how they go together.&lt;/p&gt;
&lt;h3 id=&quot;article-schema-file&quot; tabindex=&quot;-1&quot;&gt;Article schema file&lt;/h3&gt;
&lt;p&gt;The article.njk schema file in full&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{

&amp;quot;@type&amp;quot;: &amp;quot;Article&amp;quot;,

&amp;quot;@id&amp;quot;: &amp;quot;{{ site.url }}{{ page.url }}#article&amp;quot;,

&amp;quot;headline&amp;quot;: &amp;quot;{{ title }}&amp;quot;,

&amp;quot;datePublished&amp;quot;: &amp;quot;{{ page.date.toISOString() }}&amp;quot;,

&amp;quot;dateModified&amp;quot;: {% if dateUpdated %}&amp;quot;{{ dateUpdated.toISOString() }}&amp;quot;{% else %}&amp;quot;{{ page.date.toISOString() }}&amp;quot;{% endif %},

&amp;quot;image&amp;quot;: {

&amp;quot;@type&amp;quot;: &amp;quot;ImageObject&amp;quot;,

&amp;quot;url&amp;quot;: &amp;quot;{{ site.url }}{{ image }}&amp;quot;,

&amp;quot;inLanguage&amp;quot;: &amp;quot;en-GB&amp;quot;

},

&amp;quot;author&amp;quot;: {

&amp;quot;@type&amp;quot;: &amp;quot;Person&amp;quot;,

&amp;quot;@id&amp;quot;: &amp;quot;{{ site.url }}/#person&amp;quot;,

&amp;quot;name&amp;quot;: &amp;quot;Simon Cox&amp;quot;

},

&amp;quot;mainEntityOfPage&amp;quot;: {

&amp;quot;@id&amp;quot;: &amp;quot;{{ site.url }}{{ page.url }}&amp;quot;

}

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am pulling frontmatter data as well as global data - though top make it more transferrable items like name: Simon Cox could have used a placeholder instead of being hardcoded. i should clean that up so I can use this on other sites!&lt;/p&gt;
&lt;h3 id=&quot;the-collection-post-schema-file&quot; tabindex=&quot;-1&quot;&gt;The collection-post schema file&lt;/h3&gt;
&lt;p&gt;I&#39;m sure I could use some logic to simplify the number of files but this works for me at the moment.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{

&amp;quot;@type&amp;quot;: &amp;quot;CollectionPage&amp;quot;,

&amp;quot;@id&amp;quot;: &amp;quot;{{ site.url }}/post/#webpage&amp;quot;,

&amp;quot;url&amp;quot;: &amp;quot;{{ site.url }}/post/&amp;quot;,

&amp;quot;name&amp;quot;: &amp;quot;Articles&amp;quot;,

&amp;quot;description&amp;quot;: &amp;quot;A collection of in-depth articles by Simon Cox.&amp;quot;,

&amp;quot;isPartOf&amp;quot;: {

&amp;quot;@id&amp;quot;: &amp;quot;{{ site.url }}/#website&amp;quot;

},

&amp;quot;hasPart&amp;quot;: [

{%- for post in collections.Post -%}

{

&amp;quot;@type&amp;quot;: &amp;quot;Article&amp;quot;,

&amp;quot;@id&amp;quot;: &amp;quot;{{ site.url }}{{ post.url }}#webpage&amp;quot;

}{%- if not loop.last %},{% endif %}

{%- endfor -%}

]

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hope that helps someone put together their own schema on an 11ty site!&lt;/p&gt;
&lt;p&gt;To check your progress you could install my &lt;a href=&quot;https://www.simoncox.com/simons-schema/&quot;&gt;schema chrome extension&lt;/a&gt;.&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content//assets/img/content/2025-10-28-creating-a-modular-approach-to-json-schema-in-an-eleventy-website.webp" type="image" />
      <pubDate>Tue, 28 Oct 2025 00:00:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/post/2025-10-28-creating-a-modular-approach-to-json-schema-in-an-eleventy-website/</guid>
    </item>
    <item>
      <title>Creating Cloudflare redirects</title>
      <link>https://www.simoncox.com/short-articles/2025-10-08-creating-cloudflare-redirects/</link>
      <description>&lt;p&gt;I was having issues sorting out the redirects on Cloudflare and have learnt a few things on the way so am documenting them here – because I will forget it all whilst in the pursuit of happier things.&lt;/p&gt;
&lt;h2 id=&quot;directory-migration&quot; tabindex=&quot;-1&quot;&gt;Directory migration&lt;/h2&gt;
&lt;p&gt;I made a major change to the structure of a section of my site /shorts/ has reverted back to &lt;a href=&quot;https://www.simoncox.com/short-articles/&quot;&gt;/short-articles/&lt;/a&gt; as I am testing out a possible issue with &lt;a href=&quot;https://www.simoncox.com/post/2025-04-07-recovery-from-a-bing-de-indexing/&quot;&gt;this sites current  lack of SERP visibility in Bing&lt;/a&gt;. As such I needed to revert the redirects from /short-articles/ to /shorts/ back again. Not usually an issue for my skills but I thought I&#39;d make some notes.&lt;/p&gt;
&lt;h2 id=&quot;cloudflare-hosting&quot; tabindex=&quot;-1&quot;&gt;Cloudflare hosting&lt;/h2&gt;
&lt;p&gt;This site is currently hosted on Cloudflare pages, auto deployed from its github repository. I can use the inbuilt redirect solution that Cloudflare provides but that has a very limited capacity so I have created a file named _redirects that Cloudflare recognises (as does Netlify) and uses for redirects. This is in my 11ty setup and has a passthrough so that it is output in the build exactly the same as I have written it.&lt;/p&gt;
&lt;p&gt;This file can have up to 2,000 redirects if properly formatted. I have had issues with only being able to use 120 redirects but this was because I had built some of them incorrectly.&lt;/p&gt;
&lt;h3 id=&quot;deployment-logs&quot; tabindex=&quot;-1&quot;&gt;Deployment logs&lt;/h3&gt;
&lt;p&gt;One source of info that is really useful is the deployment log files. Find it here:
Cloudflare &amp;gt; Compute (Workers) &amp;gt; your site &amp;gt; View details&lt;/p&gt;
&lt;p&gt;Now scroll down in the Build log and it will tell you all sorts of interesting things such as time and what happened. This includes parsing the redirects file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;10:41:26.990	Parsed 83 valid redirect rules.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The log helpfully tells you redirects that have not been implemented and also provides some optimisation suggestions such as the order of the redirects.&lt;/p&gt;
&lt;h2 id=&quot;notes-on-cloudflare-redirect-rules-best-practices&quot; tabindex=&quot;-1&quot;&gt;Notes on Cloudflare redirect rules best practices&lt;/h2&gt;
&lt;h3 id=&quot;exclamation-mark-on-the-end-of-the-rule&quot; tabindex=&quot;-1&quot;&gt;Exclamation mark on the end of the rule&lt;/h3&gt;
&lt;p&gt;I think this was a leftover from Netlify&#39;s redirect rules&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;http://simoncox.com/*   https://www.simoncox.com/:splat  301!
Valid status codes are 200, 301, 302 (default), 303, 307, or 308. Got 301!.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I did a find and replace and removed the exclamations marks.&lt;/p&gt;
&lt;p&gt;There was another issue with this particular rule though!&lt;/p&gt;
&lt;h3 id=&quot;only-relative-urls-are-allowed&quot; tabindex=&quot;-1&quot;&gt;Only relative URLs are allowed&lt;/h3&gt;
&lt;p&gt;I had some domain redirects in place, &lt;a href=&quot;https://httpscolonforwardslashforwardslash.com/&quot;&gt;because you can&#39;t have enough domain names&lt;/a&gt;, but Cloudflare doesn&#39;t like them as the source URL, they have to be a part of the directory structure, so I had to take them out.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://www.tagsoup.net/*  https://www.simoncox.com/:splat  301!
Only relative URLs are allowed. Skipping absolute URL https://www.tagsoup.net/*.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am now forwarding those domains using an external method.&lt;/p&gt;
&lt;h3 id=&quot;redirect-rule-spaces-and-or-tabs&quot; tabindex=&quot;-1&quot;&gt;Redirect rule spaces and or tabs&lt;/h3&gt;
&lt;p&gt;Cloudflare is quite particular about the number of spaces - it looks for gaps in the redirect rule of 2 and 3 sets of spaces or tabs. If there are 4 or more sets of spaces and the rule will be ignored.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/blog/category:Model Railways /narrow-gauge-modelling/ 301
Expected exactly 2 or 3 whitespace-separated tokens. Got 4.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This means if your URL has a space you will need to use %20 in place of the space:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/blog/category:Model%20Railways /narrow-gauge-modelling/ 301
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;colons-interpreted-as-placeholders&quot; tabindex=&quot;-1&quot;&gt;Colons interpreted as placeholders&lt;/h3&gt;
&lt;p&gt;I have some URLs with colons in them, such as /blog/category:things, and have put these under section 2 as the colon is interpreted as a placeholder, or you can URL-encode the colon of course!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/blog/category%3AModel%20Railways /narrow-gauge-modelling/ 301
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;order-of-redirect-rules&quot; tabindex=&quot;-1&quot;&gt;Order of redirect rules&lt;/h3&gt;
&lt;p&gt;For performant reasons it is better to list static redirects before dynamic ones so that Cloudflare’s systems can run these more effectively:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Static rules - /home, /about, /contact&lt;/li&gt;
&lt;li&gt;Rules with placeholders - /blog/:slug, /users/:id&lt;/li&gt;
&lt;li&gt;Rules with splats - /old-site/*&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I split these up using # comments in my redirect files.&lt;/p&gt;
&lt;h2 id=&quot;final-thoughts-about-the-cloudflare-redirect-file-rules&quot; tabindex=&quot;-1&quot;&gt;Final thoughts about the Cloudflare redirect file rules&lt;/h2&gt;
&lt;p&gt;I originally thought I could switch the sites hosting between Cloudflare and Netlify hosting by just changing the DNS, a very handy and quick solution, but I am not going to have to keep two sets of redirect files if I want to do this as the rules are quite different between them.&lt;/p&gt;
&lt;p&gt;Having learnt more about the Cloudflare redirect rules If am much happier running the rules from this file. Also, this started off as a shorticle but is long enough to be a full article.&lt;/p&gt;
&lt;p&gt;You can read more on &lt;a href=&quot;https://developers.cloudflare.com/rules/url-forwarding/&quot;&gt;Cloudflare’s full documentation on redirects&lt;/a&gt; and let me know if I have missed anything important out!&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Wed, 08 Oct 2025 01:00:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2025-10-08-creating-cloudflare-redirects/</guid>
    </item>
    <item>
      <title>Creating a blogroll page from Mastodon bookmarks</title>
      <link>https://www.simoncox.com/post/2025-04-04-creating-a-blogroll-page-from-mastodon-bookmarks/</link>
      <description>&lt;h2 id=&quot;why-did-i-want-a-bookmarks-page%3F&quot; tabindex=&quot;-1&quot;&gt;Why did I want a bookmarks page?&lt;/h2&gt;
&lt;p&gt;A thing that has been on &lt;a href=&quot;https://www.simoncox.com/ideas/&quot;&gt;my ideas list&lt;/a&gt; for quite some time is to create a links type page from the Toots I bookmark on Mastodon. The mastodon bookmarks are really handy for items that I want to go back to, to read more or as a prompt to get me to do something. Having them actually on my website makes it more like a blogroll of old and &lt;a href=&quot;https://www.simoncox.com/bookmarks/&quot;&gt;here is my bookmarks page&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;mastodon-api&quot; tabindex=&quot;-1&quot;&gt;Mastodon API&lt;/h2&gt;
&lt;p&gt;Mastodon has an API that you can pull many interesting things out of and this was what got me thinking about this idea in the first place. It has been on the ideas list for a few years because I can&#39;t really write Javascript. I can look through it and make some good assumptions to whats happening but coding this is still a dark art to me. The &lt;a href=&quot;https://docs.joinmastodon.org/methods/bookmarks/&quot;&gt;Mastodon API docs&lt;/a&gt; are available to peruse and I had a glance at one point.&lt;/p&gt;
&lt;h2 id=&quot;down-the-rabbit-hole-of-code-i-go&quot; tabindex=&quot;-1&quot;&gt;Down the rabbit hole of code I go&lt;/h2&gt;
&lt;p&gt;So I turned to AI. Of course I did, and if you think less of me for it then that&#39;s just fine with me and no doubt you will give me some grief on Mastodon. Off you toddle.&lt;/p&gt;
&lt;p&gt;Meanwhile for those of you that are still interested I went through a fair bit of prompting and trial and error to get this working in the first place and then how I wanted it to work. It wasn&#39;t 5 mins time of ChatGPT and there it was. No, it was a week of spare moments pulling out hair, trying to understand things and then trying again. In the end I got there and I did learn a lot from it.&lt;/p&gt;
&lt;p&gt;With the Mastodon API you can pull out 40 bookmarks in one go - you can pull out more but then you have to call the API again asking for pagination and I have not had time to work out how to do that properly yet. I may not ever bother as 40 takes me back quite a while as I don&#39;t bookmark that often, though I might do more of it now!&lt;/p&gt;
&lt;h3 id=&quot;the-environment-file&quot; tabindex=&quot;-1&quot;&gt;The environment file&lt;/h3&gt;
&lt;p&gt;First I had to set up a .env file with my Instance and Access token at root level in my 11ty folder so that the script to make the authenticated call. In this file I added the following two lines (I have not filled in the instance or token in this example!):
&lt;code&gt;MASTODON_INSTANCE=https://your.instance MASTODON_ACCESS_TOKEN=your_access_token&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;My instance being the Mastodon server I am on. The Mastodon Access Token I needed to create by going to my Mastodon Preferences &amp;gt; Development to create New application. I give the Application a name and then at the top of the page I found my access token - it&#39;s a long string. Next I choose the Scope - read:bookmarks is all that I needed for this and then I saved the application down at the bottom with the Save Changes button.&lt;/p&gt;
&lt;p&gt;I added those two values to my .env file.&lt;/p&gt;
&lt;h3 id=&quot;the-bookmarks-script&quot; tabindex=&quot;-1&quot;&gt;The bookmarks Script&lt;/h3&gt;
&lt;p&gt;Next I created a bookmarks.js file in my _data folder and this is my current script:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Load environment variables from the .env file
require(&amp;quot;dotenv&amp;quot;).config();

// Import EleventyFetch for fetching remote data and caching it
const EleventyFetch = require(&amp;quot;@11ty/eleventy-fetch&amp;quot;);

// Get Mastodon instance URL and access token from environment variables
const MASTODON_INSTANCE = process.env.MASTODON_INSTANCE;
const MASTODON_ACCESS_TOKEN = process.env.MASTODON_ACCESS_TOKEN;

// Helper function to check if an image URL is valid (it will try to fetch only the header)
async function checkImageExists(url) {
  try {
    // Send a HEAD request to check if the image exists without downloading it
    const response = await fetch(url, { method: &amp;quot;HEAD&amp;quot; });
    return response.ok; // If the response status is 2xx, the image exists
  } catch (error) {
    // If there&#39;s an error (network issue, or image doesn&#39;t exist), return false
    return false;
  }
}

// Helper function to extract the &#39;next&#39; page URL from the Link header (used for pagination)
function getNextPage(linkHeader) {
  // If the link header is missing, there&#39;s no next page
  if (!linkHeader) return null;

  // Regular expression to extract the &#39;next&#39; link from the pagination header
  const match = linkHeader.match(/&amp;lt;([^&amp;gt;]+)&amp;gt;;&#92;s*rel=&amp;quot;next&amp;quot;/);
  return match ? match[1] : null; // Return the next page URL or null if not found
}

// Main function to fetch and process Mastodon bookmarks
module.exports = async function () {
  // Check if the required environment variables are set, otherwise log an error
  if (!MASTODON_INSTANCE || !MASTODON_ACCESS_TOKEN) {
    console.error(&amp;quot;Missing Mastodon credentials in .env file&amp;quot;);
    return []; // Return an empty array if credentials are missing
  }

  // Construct the URL to fetch bookmarks from Mastodon API
  const url = `${MASTODON_INSTANCE}/api/v1/bookmarks?limit=40`; // Fetch up to 40 bookmarks
  // Add the authorization header with the Mastodon access token
  const headers = { Authorization: `Bearer ${MASTODON_ACCESS_TOKEN}` };

  try {
    // Use EleventyFetch to fetch the bookmarks with caching for 12 hours
    const data = await EleventyFetch(url, {
      duration: &amp;quot;12h&amp;quot;,  // Cache the result for 12 hours
      type: &amp;quot;json&amp;quot;,     // Expect JSON data from the API
      fetchOptions: { headers } // Include the headers (with the access token)
    });

    // Process the fetched data (map over each bookmark and handle the media)
    return await Promise.all(
      data.map(async bookmark =&amp;gt; {
        // Check for images in the media_attachments array and validate them
        const images = await Promise.all(
          bookmark.media_attachments
            .filter(attachment =&amp;gt; attachment.type === &amp;quot;image&amp;quot;) // Filter only image attachments
            .map(async attachment =&amp;gt; {
              // For each image, check if it exists by using the checkImageExists function
              if (await checkImageExists(attachment.url)) {
                return attachment.url; // Return the image URL if valid
              }
              return null; // Return null if the image doesn&#39;t exist
            })
        );

        // Return a simplified structure for each bookmark with the relevant data
        return {
          id: bookmark.id,  // Bookmark ID
          content: bookmark.content,  // Bookmark content (text)
          url: bookmark.url,  // URL of the bookmarked post
          created_at: bookmark.created_at,  // Timestamp when the bookmark was created
          account: {
            username: bookmark.account.username,  // Account username
            url: bookmark.account.url,  // Account URL
            avatar: bookmark.account.avatar  // Account avatar URL
          },
          images: images.filter(img =&amp;gt; img !== null) // Remove null image entries
        };
      })
    );
  } catch (error) {
    // If there was an error fetching data, log it and return an empty array
    console.error(&amp;quot;Failed to fetch Mastodon bookmarks:&amp;quot;, error);
    return [];
  }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;page-code&quot; tabindex=&quot;-1&quot;&gt;Page code&lt;/h2&gt;
&lt;p&gt;To display the output I set up the following. I have the styles inline at the moment as I am still mucking around with it so they may well end up in the site css.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{% for bookmark in bookmarks %}
&amp;lt;section style=&amp;quot;border: 1px solid #ccc; padding: 10px; margin: 20px auto; border-radius: 20px;max-width:360px;overflow-wrap:anywhere;&amp;quot;&amp;gt;
	&amp;lt;img style=&amp;quot;width:40px;margin:0&amp;quot; src=&amp;quot;{{ bookmark.account.avatar }}&amp;quot; alt=&amp;quot;{{ bookmark.account.username }}&amp;quot; width=&amp;quot;40&amp;quot; height=&amp;quot;40&amp;quot;&amp;gt;
	&amp;lt;p&amp;gt;from {{ bookmark.account.username }}&amp;lt;/p&amp;gt;
	&amp;lt;p&amp;gt;{{ bookmark.content | safe }}&amp;lt;/p&amp;gt;
	{% if bookmark.images.length &amp;gt; 0 %}
	&amp;lt;section class=&amp;quot;images&amp;quot;&amp;gt;
		{% for image in bookmark.images %}
		&amp;lt;img src=&amp;quot;{{ image }}&amp;quot; alt=&amp;quot;Mastodon image&amp;quot; /&amp;gt;
		{% endfor %}
	&amp;lt;/section&amp;gt;
	{% endif %}
	&amp;lt;small&amp;gt;&amp;lt;a href=&amp;quot;{{ bookmark.url }}&amp;quot;&amp;gt;Link to the the Toot&amp;lt;/a&amp;gt; – Saved on {{ bookmark.created_at }}&amp;lt;/small&amp;gt;
&amp;lt;/section&amp;gt;
{% endfor %}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;process-of-adding-the-bookmarks&quot; tabindex=&quot;-1&quot;&gt;Process of adding the bookmarks&lt;/h2&gt;
&lt;p&gt;I did not want this process to be client side as it would have taken too long to load the page and there was a bigger risk of exposing my token. So I have this setup to build out the page when I run my build command locally. the html page gets build and the images added from cache to the img folder. That is then submitted to Github and deployed to the server.&lt;/p&gt;
&lt;p&gt;The disadvantage with this is that I need to go through a build process to get the latest 40 bookmarks onto the page. I am always tinkering with this site though so that&#39;s not a problem for me!&lt;/p&gt;
&lt;h2 id=&quot;what-next%3F&quot; tabindex=&quot;-1&quot;&gt;What next?&lt;/h2&gt;
&lt;p&gt;Hopefully some others will find this useful and create something similar if not a lot better and I await for you to post on Mastodon so that I can bookmark them!&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content//assets/img/content/2025-04-04-creating-a-blogroll-page-from-mastodon-bookmarks.webp" type="image" />
      <pubDate>Fri, 04 Apr 2025 01:00:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/post/2025-04-04-creating-a-blogroll-page-from-mastodon-bookmarks/</guid>
    </item>
    <item>
      <title>11ty Git Commit Messages</title>
      <link>https://www.simoncox.com/short-articles/2024-12-14-git-commit-messages/</link>
      <description>&lt;p&gt;Just read &lt;a href=&quot;https://block81.com/blog/git-commit-messages&quot;&gt;Git Commit Messages by Angie Herrera&lt;/a&gt; who has started organising Git Commit Messages &lt;em&gt;&amp;quot;in a way that keeps things organized and makes future me a bit happier and less stressed&amp;quot;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What a great idea!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I decided I am going to do the same – so I copied Angie&#39;s bullet points into a Note and then started thinking about it. Angie is a very accomplished Craft CMS developer, who I have been honoured to provide some SEO work, so the list makes perfect sense for a Craft build. However with 11ty builds I needed something a little more because I am now also making content changes in my 11ty builds.&lt;/p&gt;
&lt;p&gt;So here is my extended version:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;feat:&lt;/strong&gt; anything feature related, even if deleting code or making changes to existing features&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fix:&lt;/strong&gt; fixing a bug or issue without new feature code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;refactor:&lt;/strong&gt; code change that neither fixes a bug nor adds a feature but somehow improves the codebase (for me this is usually streamlining CSS)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cms:&lt;/strong&gt; changes to the CMS (version updates or plugin updates, installs, or removals)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;build:&lt;/strong&gt; Changes that affect the build system or external dependencies, such as npm, DDEV setup, or Laravel Mix.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;content:&lt;/strong&gt; New content, images and typo fixes and corrections&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;seo:&lt;/strong&gt; Changes optimising code or content for seo purposes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That should see me right!&lt;/p&gt;
</description>
      
      <pubDate>Sat, 14 Dec 2024 11:49:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2024-12-14-git-commit-messages/</guid>
    </item>
    <item>
      <title>11ty upgrading node in netlify</title>
      <link>https://www.simoncox.com/short-articles/2024-10-15-11ty-upgrading-node-in-netlify/</link>
      <description>&lt;p&gt;I upgraded the image plugin for 11ty on a small site which had an unintended chain of issues!&lt;/p&gt;
&lt;p&gt;I noticed that the Source control had node elements in it,  even though I have node_modules in my gitignore file. After some investigation and testing I realised that I must have deployed the site before adding the gitignore. Really should not have node_modules deployed to the repository even though it is private.&lt;/p&gt;
&lt;p&gt;To remove the node_modules from the repository I moved the folder up a level and committed and synced the files. That removed the node_modules from the repository. I then moved the node_modules folder back into the local site and ran a build - all was ok.&lt;/p&gt;
&lt;p&gt;I checked Netlify and the build had failed.&lt;/p&gt;
&lt;p&gt;It turned out (i.e. head scratching and testing for a while) is wasn&#39;t my local Node but the Node version on Netlify that needed upgrading - of course it was.&lt;/p&gt;
&lt;p&gt;With the node_modules in the build, Netlify had used the node_modules I had provided to create the build - which is a great feature but not what was needed. As soon as I had removed them Netlify used the default node_modules which failed to build because apparently node needed upgrading.&lt;/p&gt;
&lt;p&gt;On the Netlify Site Configuration &amp;gt; Build &amp;amp; Deploy &amp;gt; Dependency management (scroll down) to find and configure the Netlify version of Node - it was 15 and I apparently needed 18, so set to 20. Bingo - built and deployed magnificently!&lt;/p&gt;
&lt;p&gt;I hope this note helps someone but it is really for me the next time I get this issue on another site and don&#39;t realise I fixed it before.&lt;/p&gt;
</description>
      
      <pubDate>Tue, 15 Oct 2024 12:45:29 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2024-10-15-11ty-upgrading-node-in-netlify/</guid>
    </item>
    <item>
      <title>Newspaper style layout for my content</title>
      <link>https://www.simoncox.com/short-articles/2024-09-14-newspaper-style-layout-for-my-content/</link>
      <description>&lt;p&gt;I read a &lt;a href=&quot;https://rrier.fr/@pc/statuses/01J7HCPPS8C3MDYJM353A1PCXX&quot;&gt;short post on Mastodon&lt;/a&gt; from Pierre Carrier saying that his blog had a &lt;a href=&quot;https://nothing.pcarrier.com/news&quot;&gt;newspaper mode&lt;/a&gt; - and it looks great! Pierre has his site on &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;11ty&lt;/a&gt;, as my site currently is, so I thought I would have a quick go at building a newspaper version of my content - the &lt;a href=&quot;https://www.simoncox.com/news/&quot;&gt;Simon Cox Evening News&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First off I didn&#39;t want to change any of the code for my site and this would be on one page only - not a toggle between site designs. 11ty automatically builds collections to gather content into groups so with testing I picked my Shorts collection of posts and built a small piece of html to reiterate over each story - that pulls in the heading, link and content etc.&lt;/p&gt;
&lt;p&gt;This gave me a long page of content. What I wanted to do was have columns of content. CSS grid sprang to mind but of course it segments articles into blocks with spaces in the rows, so that would not work. A masonary type approach might work - but that runs in rows. So I went back to an old favourite that, in my opinion, does not get used enough on the web - columns. This is really old CSS and for various reasons designers appear not to like it - control of the flow being one of them.&lt;/p&gt;
&lt;p&gt;The design and html for the page is standalone - it does not uses any of the CSS or templates from the rest of the site.&lt;/p&gt;
&lt;p&gt;I had some issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Initially I set media breakpoints for the number of columns to give a responsive layout depending on viewport size. Pierre rightly asked why I had not set the column widths and he was spot on - that was a much better approach.&lt;/li&gt;
&lt;li&gt;Image widths had to be set to width of 100% to fill the column correctly but some were smaller than the columns widths so Max-width 100% was used.&lt;/li&gt;
&lt;li&gt;I was getting a lot of white space to the right meaning there was a lot of horizontal scrolling which was not great. I eventually tracked this down to the pre tag, that I was wrapping code in, needing white-space: pre-wrap; in the css.&lt;/li&gt;
&lt;li&gt;I had used the Shorts collection to test and swapped that to my posts collection to do a second test. What I really wanted to do was both and I thought I would have to set up a new filter in  11ty to do that bet remembered I have already done this for the rss feed – so I was able to use the feed collection! 11ty does make this kind of thing easy!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once I had the layout sorted I added some enhancements.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The images and links were in colour and I wanted an old newspaper feel. I added filter:grayscale(1) brightness(80%) contrast(150%); mix-blend-mode: hard-light; to the container making everything monochrome without touching the source content.&lt;/li&gt;
&lt;li&gt;background - a seamless crumpled paper image.&lt;/li&gt;
&lt;li&gt;post titles were set in Playfair Bold and the kerning tightened.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Things to do:
I was hoping to add some filters to make the images look like halftones but after a lot of experimentation it has eluded me. There are some lovely online codepens and &lt;a href=&quot;https://leanrada.com/notes/pure-css-halftone/&quot;&gt;blog posts on halftones&lt;/a&gt; for this but I could not get them to work without changing the posts underlying code. I may come back to this in the future.&lt;/p&gt;
&lt;p&gt;As &lt;a href=&quot;https://s3th.me/@pch/113133004239742917&quot;&gt;Seth Goldstein said It&#39;s overwhelming&lt;/a&gt; but he is a recovering journalist.&lt;/p&gt;
&lt;p&gt;Anyway - here it is - the &lt;a href=&quot;https://www.simoncox.com/news/&quot;&gt;Simon Cox Evening News&lt;/a&gt;.
&lt;img src=&quot;https://www.simoncox.com/assets/img/content/2024-09-14-newspaper-style-layout-for-my-content-1.png&quot; alt=&quot;Simon Cox Evening News screenshot showing the newspaper style layout over 9 columns on a wide screen&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;update&quot; tabindex=&quot;-1&quot;&gt;Update&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;15 Sept 2024&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I have added a couple of extra pages that filter the Articles and Short articles so it is a little bit easier to read. Not sure this will have a huge amount of traffic as it is more of an excercise! I am, of course, monitoring what happens from an SEO aspect - always testing!&lt;/p&gt;
</description>
      
      <pubDate>Sat, 14 Sep 2024 10:40:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2024-09-14-newspaper-style-layout-for-my-content/</guid>
    </item>
    <item>
      <title>11ty collections tag links</title>
      <link>https://www.simoncox.com/short-articles/2024-03-17-11ty-collection-tag-links/</link>
      <description>&lt;p&gt;More of a reminder for myself next time Image need to do this!&lt;/p&gt;
&lt;h2 id=&quot;adding-a-collection-tag-to-a-post-as-a-link&quot; tabindex=&quot;-1&quot;&gt;Adding a collection tag to a post as a link&lt;/h2&gt;
&lt;p&gt;There are some lovely ways to automate sets of tags with a list page. Hoever I don&#39;t think these can have additional content to make them into a proper topic hub page so I am building them out manually.&lt;/p&gt;
&lt;p&gt;For posts in my Articles and Shorts sections I have started adding tags to the modelling topic ones. After the author sign off with date, and update date if there is one, I have added links to the tag hub page.&lt;/p&gt;
&lt;p&gt;I started with this 11ty code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{% if tag == &amp;quot;Modelling&amp;quot; %}| &amp;lt;a href=&amp;quot;/narrow-gauge-modelling&amp;quot;&amp;gt;Modelling&amp;lt;/a&amp;gt;{% endif %}
{% if tag == &amp;quot;Loxley&amp;quot; %}| &amp;lt;a href=&amp;quot;/loxleybarton&amp;quot;&amp;gt;Loxley Barton Falls&amp;lt;/a&amp;gt;{% endif %} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But it wasn&#39;t showing up the tag links.
Turns out that because I have multiple tags on some in this form:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tags:
- Loxley
- Modelling
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Turns out that 11ty concatenates them as a string, of course, so I need to cycle through that and pull out the tags that I need.&lt;/p&gt;
&lt;p&gt;This gave me:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{% for tag in tags %} 
  {% if tag == &amp;quot;Modelling&amp;quot; %}| &amp;lt;a href=&amp;quot;/narrow-gauge-modelling&amp;quot;&amp;gt;Modelling&amp;lt;/a&amp;gt;{% endif %}
  {% if tag == &amp;quot;Loxley&amp;quot; %}| &amp;lt;a href=&amp;quot;/loxleybarton&amp;quot;&amp;gt;Loxley Barton Falls&amp;lt;/a&amp;gt;{% endif %}
{%- endfor %}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which works perfectly. I am sure there is a more robust method but for now, for me, this is working great!&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Sun, 17 Mar 2024 12:40:20 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2024-03-17-11ty-collection-tag-links/</guid>
    </item>
    <item>
      <title>Tracking 404 broken links with Fathom Analytics</title>
      <link>https://www.simoncox.com/short-articles/2024-02-11-tracking-broken-links-with-fathom/</link>
      <description>&lt;p&gt;I switched all my small projects over to Fathom Analytics in 2023 for various reasons but there was one page on my site where I kept the Google Analytics code - the 404 page.&lt;/p&gt;
&lt;p&gt;I did this so that I could pull the data into a Data Studio dashboard to provide me with errant URLs being visited on my site.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.simoncox.com/assets/img/content/2024-02-11-tracking-broken-links-with-fathom-looker-studio.png&quot; alt=&quot;Simon&#39;s 404 URL table in Data Studio&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The above image shows a classic example of a URL that didn&#39;t exist on my site. Not sure how someone got this wrong but they have missed one letter, &#39;e&#39; out of the URL thus breaking it! They have put:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/post/2010-02-04-th-perfect-angle-to-staple-paper/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;when the actual page is at:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/post/2010-02-04-the-perfect-angle-to-staple-paper/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it had nine visits (probably the same person wondering why the link was going to my 404 page - so they may have fixed it.)&lt;/p&gt;
&lt;p&gt;So the report is super useful to see what is going on under the hood.&lt;/p&gt;
&lt;h2 id=&quot;why-do-i-want-to-see-what-is-happening-on-my-404-page%3F&quot; tabindex=&quot;-1&quot;&gt;Why do I want to see what is happening on my 404 page?&lt;/h2&gt;
&lt;p&gt;Well, broken URLs in my site can usually be found quite easily by running a crawler across the site and fixing anything that breaks but there is the odd occasion where someone linking to my site uses an old URL or creates a URL with a typo in it - essentially they have created a broken link to my site and I don&#39;t know who has done that and I can&#39;t ask them to fix it.&lt;/p&gt;
&lt;p&gt;With the old URLs I have redirects in place to catch them but for new broken URLs I don&#39;t know they exist unless I can track the referrer. So that&#39;s what I have been doing.&lt;/p&gt;
&lt;h2 id=&quot;set-up-the-redirects&quot; tabindex=&quot;-1&quot;&gt;Set up the Redirects&lt;/h2&gt;
&lt;p&gt;When I get a new broken link I can add a line to my redirects file to redirect that to the appropriate page if one exists. If it is not obvious where to send the traffic then I still let is resolve to the 404 page.&lt;/p&gt;
&lt;h2 id=&quot;creating-this-report-in-fathom-analytics&quot; tabindex=&quot;-1&quot;&gt;Creating this report in Fathom Analytics&lt;/h2&gt;
&lt;p&gt;I thought I should be able to create a similar report using Fathom Analytics so read the &lt;a href=&quot;https://usefathom.com/docs/features/events&quot;&gt;Creating and using events documentation&lt;/a&gt; and it looked like I could set an event up and track them there.&lt;/p&gt;
&lt;p&gt;This code looked good so I tried it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;
window.addEventListener(&#39;load&#39;, (event) =&amp;gt; {
  fathom.trackEvent(&#39;checkout completed&#39;);
});
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All I needed to do was change the checkout completed to 404. It worked but of course only told me that there was a 404 event. I needed more data from the script - I needed the URL. Javasripty people will be well ahead of me now and using the word &#39;just&#39; a lot but despite using the &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;fabulous 11ty&lt;/a&gt; for this site I really can&#39;t cope with much more than a sprinkle of javascript.&lt;/p&gt;
&lt;h2 id=&quot;fathom-to-the-rescue&quot; tabindex=&quot;-1&quot;&gt;Fathom to the rescue&lt;/h2&gt;
&lt;p&gt;So I contacted Fathom Analytics, and told them what I was trying to do. The wonderful Paul Jarvis came back with the code I needed and even tested it out before sending it to me!&lt;/p&gt;
&lt;p&gt;Here is the code I have ended up using - courtesy of Paul.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;
document.addEventListener(&#39;DOMContentLoaded&#39;, function() {
    var path = window.location.pathname;
    fathom.trackEvent(&#39;404: &#39; + path);
  });
&amp;lt;/script&amp;gt;	
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On testing, I now get the following report in my Fathom Dashboard:
&lt;img src=&quot;https://www.simoncox.com/assets/img/content/2024-02-11-tracking-broken-links-with-fathom-fathom-dashboard.png&quot; alt=&quot;Simon&#39;s 404 URL table in Fathom Analytics Dashboard&quot; /&gt;&lt;/p&gt;
&lt;p&gt;That allows me to spot 404 URL errors and set up new redirects for them!&lt;/p&gt;
&lt;h2 id=&quot;fathom-analytics&quot; tabindex=&quot;-1&quot;&gt;Fathom Analytics&lt;/h2&gt;
&lt;p&gt;Thank you Paul Jarvis for your help on this.
If you are interested in &lt;a href=&quot;https://usefathom.com/ref/ILRGSP&quot;&gt;Fathom Analytics, this is my affiliate linky&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;update&quot; tabindex=&quot;-1&quot;&gt;Update&lt;/h2&gt;
&lt;p&gt;Paul has already added &lt;a href=&quot;https://usefathom.com/docs/events/404-page-tracking#track-404-error-pages&quot;&gt;this technique to the Fathom documentation&lt;/a&gt;!&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Sun, 11 Feb 2024 00:00:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2024-02-11-tracking-broken-links-with-fathom/</guid>
    </item>
    <item>
      <title>Cleaning up the 11ty config</title>
      <link>https://www.simoncox.com/short-articles/2023-10-29-cleaning-up-the-11ty-config/</link>
      <description>&lt;p&gt;I read a couple of articles this week on cleaning up your 11ty config file, the initial one that I found from &lt;a href=&quot;https://moosedog.io/posts/clean-configuration-file-in-eleventy.html&quot;&gt;Robin Hoover&lt;/a&gt; and the second from &lt;a href=&quot;https://www.lenesaile.com/en/blog/organizing-the-eleventy-config-file/&quot;&gt;Lene Saile&lt;/a&gt; in which Lene had added a 3rd method, adding another config file as a plugin which I then understood what I could do. Yes takes me a bit of time sometimes.&lt;/p&gt;
&lt;p&gt;I created a new folder named _11ty in my source folder and in that added new .js files for each of the plugins, functions, filters and collections I needed, and in each added the code for them. This included the module.exports section but with slightly changed code.&lt;/p&gt;
&lt;p&gt;plugin.js code example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const CleanCSS = require(&amp;quot;clean-css&amp;quot;);

module.exports = eleventyConfig =&amp;gt; {
  eleventyConfig.addFilter(&amp;quot;cssmin&amp;quot;, function(code) {
    return new CleanCSS({}).minify(code).styles;
  });
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The module.exports line has changed from:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module.exports = function(eleventyConfig) {
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module.exports = eleventyConfig =&amp;gt; {
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With all the plugin and filter code tucked into its own file for convenience and ease of maintenance my .eleventy.js file now looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module.exports = function(eleventyConfig) {
  // Plugins
  eleventyConfig.addPlugin(require(&amp;quot;./src/_11ty/cssmini.js&amp;quot;)); // CSS minification
  eleventyConfig.addPlugin(require(&amp;quot;./src/_11ty/rss.js&amp;quot;)); // RSS feed plugin
  eleventyConfig.addPlugin(require(&amp;quot;./src/_11ty/datetime.js&amp;quot;)); // Date Time plugin
  eleventyConfig.addPlugin(require(&amp;quot;./src/_11ty/collections.js&amp;quot;)); // Collections
  eleventyConfig.addPlugin(require(&amp;quot;./src/_11ty/image.js&amp;quot;)); // Image plugin
  eleventyConfig.addPlugin(require(&amp;quot;./src/_11ty/passthroughs.js&amp;quot;)); // passthroughs

  return {
    dir: {
      input: &amp;quot;src&amp;quot;,
      output: &amp;quot;public&amp;quot;
    }
  }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see the paths to each plug in I have used.&lt;/p&gt;
&lt;p&gt;Yes, this is more of a note to myself for the next time I need to do this but I hope it helps someone else too!&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Sun, 29 Oct 2023 16:11:20 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-10-29-cleaning-up-the-11ty-config/</guid>
    </item>
    <item>
      <title>11ty draft posts</title>
      <link>https://www.simoncox.com/short-articles/2023-09-01-11ty-draft-posts/</link>
      <description>&lt;h2 id=&quot;set-up-a-draft-system-in-11ty&quot; tabindex=&quot;-1&quot;&gt;Set up a draft system in 11ty&lt;/h2&gt;
&lt;p&gt;Now this and a few other sites I have are &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;running on 11ty&lt;/a&gt; I have been meaning to add a way of marking a post as a draft while I am writing it - just in case I need to publish a short while getting an article ready.&lt;/p&gt;
&lt;p&gt;There are several complex explanations of how to do this out there including one from &lt;a href=&quot;https://remysharp.com/2019/06/26/scheduled-and-draft-11ty-posts&quot;&gt;Remy Sharps from 2019&lt;/a&gt; and the &lt;a href=&quot;https://www.11ty.dev/docs/quicktips/draft-posts/&quot;&gt;Quick Tip in the 11ty docs&lt;/a&gt;. I am sure they are all great
but I wanted something simple and easy to use and I didn&#39;t need to schedule anything - well not yet anyway.&lt;/p&gt;
&lt;p&gt;I found this one on github from &lt;a href=&quot;https://github.com/pdehaan/11ty-drafts&quot;&gt;Peter Dehaan&lt;/a&gt; which explained how this works easily enough for me to comprehend and implement.&lt;/p&gt;
&lt;p&gt;With the added src.11tydata.js file all I need to is add a draft: true to the front matter and the post will not be included in the build, including lists of posts, my mxl sitemap and my rss feed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: 11ty draft posts
description: Setting a post to draft in 11ty while writing
topic: web
draft: true
---
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;update-2024%2F11%2F25&quot; tabindex=&quot;-1&quot;&gt;Update 2024/11/25&lt;/h2&gt;
&lt;p&gt;There has been un update in 11ty v3 with an &lt;a href=&quot;https://www.11ty.dev/docs/config-preprocessors/#example-drafts&quot;&gt;easier method&lt;/a&gt;&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Fri, 01 Sep 2023 17:32:12 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-09-01-11ty-draft-posts/</guid>
    </item>
    <item>
      <title>Solving a date display issue in 11ty templates</title>
      <link>https://www.simoncox.com/short-articles/2023-07-07-solving-a-date-display-issue-in-11ty-templates/</link>
      <description>&lt;p&gt;I have recently changed the &lt;a href=&quot;https://www.simoncox.com/post/2023-07-06-lastmod-in-xml-sitemap-for-11ty/&quot;&gt;lastmod date in my xml site map to be accurate&lt;/a&gt; now that Google are wanting that. Part of what Google wanted was for the page to state the update date on it. I pulled this data from the posts front matter but because I had set an 11ty filter for the sitemap the output on the page was the full UTC:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Updated:&lt;/strong&gt; &lt;strong&gt;2023-04-03T00:00:00.000&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The resolution was to add .toDateString() to the front matter item, dateUpdated, in the template giving me:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dateUpdated.toDateString()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Which displays as:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Updated:&lt;/strong&gt; &lt;strong&gt;Mon Apr 03 2023&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Far better!&lt;/em&gt;&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Fri, 07 Jul 2023 15:53:37 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-07-07-solving-a-date-display-issue-in-11ty-templates/</guid>
    </item>
    <item>
      <title>11ty image shortcode best practice</title>
      <link>https://www.simoncox.com/short-articles/2023-06-06-11ty-image-shortcode-best-practice/</link>
      <description>&lt;p&gt;Just deployed a site using the &lt;a href=&quot;https://www.11ty.dev/docs/plugins/image/&quot;&gt;11ty image plugin&lt;/a&gt; and it is working well. I did have some issues with set up - wanted the hi-res images in a separate folder outside of src and public folders and acheived that by setting an  external source -  would be nice if this were in the base set up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let imageSrc = `hi-res-images/${src}`;
let metadata = await Image(imageSrc, {    
widths: [180, 343, 647, 1200],
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then the shortcode in the functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;eleventyConfig.addAsyncShortcode(&amp;quot;image&amp;quot;, imageShortcode);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But then I was having issues where the image shown on full screen was the low res version - not good! Took me an age to work out the issue till I noticed some errant code in the source.&lt;/p&gt;
&lt;p&gt;In Markdown please leave a space before and after the image shortcode - else it gets mixed up and bits of the picture element get wrapped in a p tag and become not a picture element!&lt;/p&gt;
&lt;p&gt;This doesn&#39;t work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Lorum ipsum dolar bla bla
% image &amp;quot;image.jpg&amp;quot;, &amp;quot;alt text&amp;quot; %
Lorum ipsum dolar bla bla
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But this does:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Lorum ipsum dolar bla bla

% image &amp;quot;image.jpg&amp;quot;, &amp;quot;alt text&amp;quot; %

Lorum ipsum dolar bla bla
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Leave some space!&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Tue, 06 Jun 2023 15:46:51 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-06-06-11ty-image-shortcode-best-practice/</guid>
    </item>
    <item>
      <title>Cloudflare Pages error with 11ty build</title>
      <link>https://www.simoncox.com/short-articles/2023-05-15-cloudflare-pages-error-with-11ty-build/</link>
      <description>&lt;p&gt;I have a couple of 11ty built sites that are auto deployed out to Cloudflare Pages. I normally prefer Netlify for the hosting but I do like to keep some eggs in other baskets.&lt;/p&gt;
&lt;p&gt;I updated a site yesterday and it kept failing the deploy to Cloudflare with the error stating that Node had to be at least version 14. I checked my local Node version and it was 19.3.0. So I changed my gitignore to allow the node files to be in the deploy in the hope that this would enable Cloudflare to build out the pages  correctly.(Then I had issues with Git Authentication - another post another day on this perhaps but I had to restart my Mac to get the Auth to work.) That did not work.&lt;/p&gt;
&lt;p&gt;Turns out you have to set the Environment Variables for Node to work. This seems a bit of a faf and must be new in Cloudflare since March - the last time I deployed this site. Not sure why they have complicated things.&lt;/p&gt;
&lt;p&gt;Navigate to Pages &amp;gt; site &amp;gt; Settings &amp;gt; Environment Variables and set up a new variable named NODE_VERSION and I put the version I am using in there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.simoncox.com/assets/img/content/cloudflare-enviroment-variable-node-version.png&quot; alt=&quot;Cloudflare Pages dialogue - Enviroment Variable - Node Version 19.3.0&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And the next deployment worked!&lt;/p&gt;
&lt;h2 id=&quot;update-2024-09-29&quot; tabindex=&quot;-1&quot;&gt;Update 2024-09-29&lt;/h2&gt;
&lt;p&gt;On reflection this may have only happened when Cloudflare increased their minimum version of Node. Even though I was using 19.3.0 Cloudflare appears not to be detecting the version you have used, even though that is in the package.json, and relies on you setting it in the Environment Variables. This certainly does allow easy customisation but could be automated.&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Mon, 15 May 2023 10:05:13 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-05-15-cloudflare-pages-error-with-11ty-build/</guid>
    </item>
    <item>
      <title>11ty conditional canonical</title>
      <link>https://www.simoncox.com/short-articles/2023-02-13-11ty-conditional-canonical/</link>
      <description>&lt;p&gt;GSC was flagging some Canonical issue on this site so I decided to add the canonical using the page.url parameter in my base.njk nunjucks include.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;link rel=&amp;quot;canonical&amp;quot; href=&amp;quot;https://www.simoncox.com{{ page.url }}&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;However, I have already included a Canonical in the frontmatter of some of my posts and there may be reasons why i&#39;d want the canonical to be on a different url. So I added a conditional to state that if the frontmatter for canonical exists then use it else fall back to the standard page url version. And that gave me this:&lt;br /&gt;
&lt;code&gt;{% if canonical %}&amp;lt;link rel=&amp;quot;canonical&amp;quot; href=&amp;quot;{{ canonical }}&amp;quot;&amp;gt;{% else %}&amp;lt;link rel=&amp;quot;canonical&amp;quot; href=&amp;quot;https://www.simoncox.com{{ page.url }}&amp;quot;&amp;gt;{% endif %}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Simple but effective.
^ to &lt;a href=&quot;https://mrqwest.co.uk/blog/escaping-code-in-11ty/&quot;&gt;MrQuest for the tip showing me how to display raw njk code!&lt;/a&gt;&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Mon, 13 Feb 2023 14:17:55 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-02-13-11ty-conditional-canonical/</guid>
    </item>
    <item>
      <title>Remove 404 file from sitemap.xml in 11ty</title>
      <link>https://www.simoncox.com/short-articles/2023-02-06-remove-404-file-from-sitemap-xml-in-11ty/</link>
      <description>&lt;p&gt;I realised that the sitemap.xml file was listing the 404 page - we really don&#39;t want that in there as the search engines don&#39;t want it. &lt;a href=&quot;https://www.simoncox.com/post/2023-07-06-lastmod-in-xml-sitemap-for-11ty/&quot;&gt;The 11ty sitemap.njk file&lt;/a&gt; had the answer in its frontmatter for any page you don&#39;t want in a collection, and that includes the All collection, I added this in the frontmatter of the 404 page:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;eleventyExcludeFromCollections: true

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then any page I want to manually jeep out of the sitemap I can add &lt;em&gt;sitemapIgnore: true&lt;/em&gt; to the frontmatter.&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Mon, 06 Feb 2023 18:08:58 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-02-06-remove-404-file-from-sitemap-xml-in-11ty/</guid>
    </item>
    <item>
      <title>Webmentions</title>
      <link>https://www.simoncox.com/short-articles/2023-02-05-webmentions/</link>
      <description>&lt;p&gt;I﻿ have tried to add &lt;a href=&quot;https://en.wikipedia.org/wiki/Webmention&quot;&gt;Webmentions&lt;/a&gt; to the site having read &lt;a href=&quot;https://en.wikipedia.org/wiki/Webmention&quot;&gt;Max Böck&#39;s post&lt;/a&gt; on this and then &lt;a href=&quot;https://daily-dev-tips.com/posts/implementing-webmentions-on-a-11ty-blog/&quot;&gt;Chris Bongers post&lt;/a&gt; - both very helpful and bewildering at the same time! Have found my natural limit again having got so far with 11ty!&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Sun, 05 Feb 2023 10:55:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-02-05-webmentions/</guid>
    </item>
    <item>
      <title>Netlify CMS</title>
      <link>https://www.simoncox.com/short-articles/2023-02-04-netlify-cms/</link>
      <description>&lt;p&gt;No issues with coding the pages up as and when I need but if I am on the go somewhere making changes to the site will have to wait - except that I have now installed the Netlify CMS! It&#39;s very lightweight for a CMS and is based on the 11ty Collections so static page changes are a little more difficult but posts are ok - such as this one.&lt;/p&gt;
&lt;h2 id=&quot;update%3A&quot; tabindex=&quot;-1&quot;&gt;Update:&lt;/h2&gt;
&lt;p&gt;Netlify CMS was rebranded to Decap CMS and is now run Independently by a Netlify partner agency.
&lt;a href=&quot;https://decapcms.org/&quot;&gt;More info on Decap CMS&lt;/a&gt;.&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Sat, 04 Feb 2023 16:58:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-02-04-netlify-cms/</guid>
    </item>
    <item>
      <title>11ty starter video</title>
      <link>https://www.simoncox.com/short-articles/2023-02-03-11ty-starter-video/</link>
      <description>&lt;p&gt;There are many 11ty resources available but the one that I started with to get me going is
Kevin Powell&#39;s &lt;a href=&quot;https://www.youtube.com/watch?v=4wD00RT6d-g&quot;&gt;Turn static HTML/CSS into a blog with CMS using the JAMStack&lt;/a&gt; and I keep going back to it!&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Fri, 03 Feb 2023 09:00:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-02-03-11ty-starter-video/</guid>
    </item>
    <item>
      <title>11ty inline minified css</title>
      <link>https://www.simoncox.com/short-articles/2023-02-03-11ty-inline-minified-css/</link>
      <description>&lt;p&gt;Minifying css for 11ty sites is quick and simple. &lt;a href=&quot;https://v0-7-1.11ty.dev/docs/quicktips/inline-css/&quot;&gt;Quick Tip #001—Inline minified CSS&lt;/a&gt; Using the CleanCSS plugin and moving the css file to _includes and then pulling the code into one line in the base.njk head.&lt;/p&gt;
</description>
      
      <enclosure url="https://www.simoncox.com/assets/img/content/itsjustashort.webp" type="image" />
      <pubDate>Fri, 03 Feb 2023 09:00:00 GMT</pubDate>
      <dc:creator>Simon Cox</dc:creator>
      <guid>https://www.simoncox.com/short-articles/2023-02-03-11ty-inline-minified-css/</guid>
    </item>
  </channel>
</rss>