Repository: JoshuaKGoldberg/create-typescript-app (ts)

Issue:
🐛 Bug: README.md should only include relevant badges
### Bug Report Checklist

- [x] I have tried restarting my IDE and the issue persists.
- [x] I have pulled the latest `main` branch of the repository.
- [x] I have [searched for related issues](https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=is%3Aissue) and found none that matched my issue.

### Expected

Generated `README.md` files should only include badges the package actually uses. For example, the standard npm package badge should only be included if the package is actually being published to npm.

### Actual

`blockREADME.md` always includes quite a few badges:

https://github.com/JoshuaKGoldberg/create-typescript-app/blob/c2d239b362657417b569daa56ecbe1b0306b4f99/src/blocks/blockREADME.ts#L37-L43

### Additional Info

🎁 

Pull request description:
fix: provide README badges via addons
## PR Checklist

- [x] Addresses an existing open issue: fixes #2036
- [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22)
- [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/.github/CONTRIBUTING.md) were taken

## Overview

Caught a couple of discrepancies in how the README.md badges are printed. Nice.

🎁 

Patch:
diff --git a/README.md b/README.md
index 1971f0c..f9de339 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,8 @@
 	<!-- prettier-ignore-end -->
 	<a href="https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
 	<a href="https://codecov.io/gh/JoshuaKGoldberg/create-typescript-app" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/JoshuaKGoldberg/create-typescript-app?label=%F0%9F%A7%AA%20coverage" /></a>
-	<a href="https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
-	<a href="http://npmjs.com/package/create-typescript-app"><img alt="📦 npm version" src="https://img.shields.io/npm/v/create-typescript-app?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
+	<a href="https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg" /></a>
+	<a href="http://npmjs.com/package/create-typescript-app" target="_blank"><img alt="📦 npm version" src="https://img.shields.io/npm/v/create-typescript-app?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
 	<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 </p>
 
diff --git a/src/blocks/blockAllContributors.ts b/src/blocks/blockAllContributors.ts
index 1a2fb2b..91f1108 100644
--- a/src/blocks/blockAllContributors.ts
+++ b/src/blocks/blockAllContributors.ts
@@ -23,11 +23,19 @@ export const blockAllContributors = base.createBlock({
 				}),
 				blockREADME({
 					badges: [
-						`<!-- prettier-ignore-start -->
-\t<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
-\t<a href="#contributors" target="_blank"><img alt="👪 All Contributors: ${contributions}" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-${contributions}-21bb42.svg" /></a>
+						{
+							alt: `👪 All Contributors: ${contributions}`,
+							comments: {
+								after: `
 <!-- ALL-CONTRIBUTORS-BADGE:END -->
 \t<!-- prettier-ignore-end -->`,
+								before: `<!-- prettier-ignore-start -->
+\t<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
+\t`,
+							},
+							href: "#contributors",
+							src: `https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-${contributions}-21bb42.svg`,
+						},
 					],
 					sections: options.contributors
 						? [printAllContributorsTable(options.contributors)]
diff --git a/src/blocks/blockCodecov.ts b/src/blocks/blockCodecov.ts
index 1045dab..e6e4700 100644
--- a/src/blocks/blockCodecov.ts
+++ b/src/blocks/blockCodecov.ts
@@ -3,6 +3,7 @@ import { z } from "zod";
 import { base } from "../base.js";
 import { resolveUses } from "./actions/resolveUses.js";
 import { blockGitHubApps } from "./blockGitHubApps.js";
+import { blockREADME } from "./blockREADME.js";
 import { blockRemoveFiles } from "./blockRemoveFiles.js";
 import { blockVitest } from "./blockVitest.js";
 
@@ -23,6 +24,15 @@ export const blockCodecov = base.createBlock({
 						},
 					],
 				}),
+				blockREADME({
+					badges: [
+						{
+							alt: "🧪 Coverage",
+							href: `https://codecov.io/gh/${options.owner}/${options.repository}`,
+							src: `https://img.shields.io/codecov/c/github/${options.owner}/${options.repository}?label=%F0%9F%A7%AA%20coverage`,
+						},
+					],
+				}),
 				blockVitest({
 					actionSteps: [
 						{
diff --git a/src/blocks/blockContributorCovenant.ts b/src/blocks/blockContributorCovenant.ts
index 301649e..7ffa0dd 100644
--- a/src/blocks/blockContributorCovenant.ts
+++ b/src/blocks/blockContributorCovenant.ts
@@ -1,4 +1,5 @@
 import { base } from "../base.js";
+import { blockREADME } from "./blockREADME.js";
 import { blockRemoveFiles } from "./blockRemoveFiles.js";
 
 export const blockContributorCovenant = base.createBlock({
@@ -7,6 +8,17 @@ export const blockContributorCovenant = base.createBlock({
 	},
 	produce({ options }) {
 		return {
+			addons: [
+				blockREADME({
+					badges: [
+						{
+							alt: "🤝 Code of Conduct: Kept",
+							href: `https://github.com/${options.owner}/${options.repository}/blob/main/.github/CODE_OF_CONDUCT.md`,
+							src: "https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42",
+						},
+					],
+				}),
+			],
 			files: {
 				".github": {
 					"CODE_OF_CONDUCT.md": `# Contributor Covenant Code of Conduct
diff --git a/src/blocks/blockMITLicense.ts b/src/blocks/blockMITLicense.ts
index 6029d5d..ace68bd 100644
--- a/src/blocks/blockMITLicense.ts
+++ b/src/blocks/blockMITLicense.ts
@@ -1,13 +1,23 @@
 import { base } from "../base.js";
 import { blockPackageJson } from "./blockPackageJson.js";
+import { blockREADME } from "./blockREADME.js";
 
 export const blockMITLicense = base.createBlock({
 	about: {
 		name: "MIT License",
 	},
-	produce() {
+	produce({ options }) {
 		return {
 			addons: [
+				blockREADME({
+					badges: [
+						{
+							alt: "📝 License: MIT",
+							href: `https://github.com/${options.owner}/${options.repository}/blob/main/LICENSE.md`,
+							src: "https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg",
+						},
+					],
+				}),
 				blockPackageJson({
 					properties: {
 						files: ["LICENSE.md"],
diff --git a/src/blocks/blockREADME.ts b/src/blocks/blockREADME.ts
index f3c2c06..b5ded0f 100644
--- a/src/blocks/blockREADME.ts
+++ b/src/blocks/blockREADME.ts
@@ -9,37 +9,47 @@ function printAttributes(attributes: Record<string, number | string>) {
 		.join(" ");
 }
 
+const zBadge = z.object({
+	alt: z.string(),
+	comments: z
+		.object({
+			after: z.string(),
+			before: z.string(),
+		})
+		.optional(),
+	href: z.string().optional(),
+	src: z.string(),
+});
+
+type Badge = z.infer<typeof zBadge>;
+
 export const blockREADME = base.createBlock({
 	about: {
 		name: "README.md",
 	},
 	addons: {
-		badges: z.array(z.string()).default([]),
+		badges: z.array(zBadge).default([]),
 		notices: z.array(z.string()).default([]),
 		sections: z.array(z.string()).default([]),
 	},
 	produce({ addons, options }) {
 		const { badges, notices, sections } = addons;
 
+		const explainer =
+			options.explainer && `\n${options.explainer.join("\n")}\n`;
+
 		const logo =
 			options.logo &&
 			`\n<img ${printAttributes({ align: "right", ...options.logo })}>\n`;
 
-		const explainer =
-			options.explainer && `\n${options.explainer.join("\n")}\n`;
-
 		return {
 			files: {
 				"README.md": `<h1 align="center">${options.title}</h1>
 
 <p align="center">${formatDescription(options.description)}</p>
 
-<p align="center">${badges.length ? badges.map((badge) => `\n\t${badge}`).join("\n") : ""}
-	<a href="https://github.com/${options.owner}/${options.repository}/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
-	<a href="https://codecov.io/gh/${options.owner}/${options.repository}" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/${options.owner}/${options.repository}?label=%F0%9F%A7%AA%20coverage" /></a>
-	<a href="https://github.com/${options.owner}/${options.repository}/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
-	<a href="http://npmjs.com/package/${options.repository}"><img alt="📦 npm version" src="https://img.shields.io/npm/v/${options.repository}?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
-	<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
+<p align="center">
+${formatBadges(badges)}
 </p>
 ${[logo, explainer].filter(Boolean).join("")}
 ## Usage
@@ -57,6 +67,35 @@ ${notices.length ? `\n${notices.map((notice) => notice.trim()).join("\n\n")}` :
 	},
 });
 
+function badgeSorter(a: Badge, b: Badge) {
+	return removeEmojis(a.alt).localeCompare(removeEmojis(b.alt));
+}
+
+function formatBadge(badge: Badge) {
+	const image = `<img alt="${badge.alt}" src="${badge.src}" />`;
+	const tagged = badge.href
+		? `<a href="${badge.href}" target="_blank">${image}</a>`
+		: image;
+	const commented = badge.comments
+		? `${badge.comments.before}${tagged}${badge.comments.after}`
+		: tagged;
+
+	return `\t${commented}`;
+}
+
+function formatBadges(badges: Badge[]) {
+	return [
+		...badges,
+		{
+			alt: "💪 TypeScript: Strict",
+			src: "https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg",
+		},
+	]
+		.sort(badgeSorter)
+		.map(formatBadge)
+		.join("\n");
+}
+
 function formatDescription(description: string) {
 	if (!description.includes(". ")) {
 		return description;
@@ -64,3 +103,7 @@ function formatDescription(description: string) {
 
 	return "\n\t" + description.replaceAll(". ", ".\n\t") + "\n";
 }
+
+function removeEmojis(text: string) {
+	return text.replaceAll(/\p{Emoji}/gu, "").trim();
+}
diff --git a/src/blocks/blockReleaseIt.ts b/src/blocks/blockReleaseIt.ts
index 43e0bc9..ad40073 100644
--- a/src/blocks/blockReleaseIt.ts
+++ b/src/blocks/blockReleaseIt.ts
@@ -3,6 +3,7 @@ import { getPackageDependencies } from "../data/packageData.js";
 import { resolveUses } from "./actions/resolveUses.js";
 import { blockCSpell } from "./blockCSpell.js";
 import { blockPackageJson } from "./blockPackageJson.js";
+import { blockREADME } from "./blockREADME.js";
 import { blockRemoveDependencies } from "./blockRemoveDependencies.js";
 import { blockRepositorySecrets } from "./blockRepositorySecrets.js";
 import { createSoloWorkflowFile } from "./files/createSoloWorkflowFile.js";
@@ -31,6 +32,15 @@ export const blockReleaseIt = base.createBlock({
 						},
 					},
 				}),
+				blockREADME({
+					badges: [
+						{
+							alt: "📦 npm version",
+							href: `http://npmjs.com/package/${options.repository}`,
+							src: `https://img.shields.io/npm/v/${options.repository}?color=21bb42&label=%F0%9F%93%A6%20npm`,
+						},
+					],
+				}),
 				blockRemoveDependencies({
 					dependencies: ["should-semantic-release"],
 				}),


Test patch:
diff --git a/src/blocks/blockAllContributors.test.ts b/src/blocks/blockAllContributors.test.ts
index 67e554a..6624e50 100644
--- a/src/blocks/blockAllContributors.test.ts
+++ b/src/blocks/blockAllContributors.test.ts
@@ -22,11 +22,19 @@ describe("blockAllContributors", () => {
 			    {
 			      "addons": {
 			        "badges": [
-			          "<!-- prettier-ignore-start -->
-				<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
-				<a href="#contributors" target="_blank"><img alt="👪 All Contributors: undefined" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-undefined-21bb42.svg" /></a>
+			          {
+			            "alt": "👪 All Contributors: undefined",
+			            "comments": {
+			              "after": "
 			<!-- ALL-CONTRIBUTORS-BADGE:END -->
 				<!-- prettier-ignore-end -->",
+			              "before": "<!-- prettier-ignore-start -->
+				<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
+				",
+			            },
+			            "href": "#contributors",
+			            "src": "https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-undefined-21bb42.svg",
+			          },
 			        ],
 			        "sections": undefined,
 			      },
@@ -110,96 +118,104 @@ describe("blockAllContributors", () => {
 		});
 
 		expect(creation).toMatchInlineSnapshot(`
-			{
-			  "addons": [
-			    {
-			      "addons": {
-			        "ignores": [
-			          "/.all-contributorsrc",
-			        ],
-			      },
-			      "block": [Function],
-			    },
-			    {
-			      "addons": {
-			        "badges": [
-			          "<!-- prettier-ignore-start -->
-				<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
-				<a href="#contributors" target="_blank"><img alt="👪 All Contributors: 1" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-1-21bb42.svg" /></a>
-			<!-- ALL-CONTRIBUTORS-BADGE:END -->
-				<!-- prettier-ignore-end -->",
-			        ],
-			        "sections": [
-			          "## Contributors
+							{
+							  "addons": [
+							    {
+							      "addons": {
+							        "ignores": [
+							          "/.all-contributorsrc",
+							        ],
+							      },
+							      "block": [Function],
+							    },
+							    {
+							      "addons": {
+							        "badges": [
+							          {
+							            "alt": "👪 All Contributors: 1",
+							            "comments": {
+							              "after": "
+							<!-- ALL-CONTRIBUTORS-BADGE:END -->
+								<!-- prettier-ignore-end -->",
+							              "before": "<!-- prettier-ignore-start -->
+								<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
+								",
+							            },
+							            "href": "#contributors",
+							            "src": "https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-1-21bb42.svg",
+							          },
+							        ],
+							        "sections": [
+							          "## Contributors
 
-			<!-- spellchecker: disable -->
-			<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
-			<!-- prettier-ignore-start -->
-			<!-- markdownlint-disable -->
-			<table>
-			  <tbody>
-			    <tr>
-			      <td align="center" valign="top" width="14.28%"><a href="http://www.joshuakgoldberg.com"><img src="https://avatars.githubusercontent.com/u/3335181?v=4?s=100" width="100px;" alt="Josh Goldberg"/><br /><sub><b>Josh Goldberg</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=author%3AJoshuaKGoldberg" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/create-typescript-app/commits?author=JoshuaKGoldberg" title="Code">💻</a> <a href="#design-JoshuaKGoldberg" title="Design">🎨</a> <a href="https://github.com/JoshuaKGoldberg/create-typescript-app/commits?author=JoshuaKGoldberg" title="Documentation">📖</a> <a href="#ideas-JoshuaKGoldberg" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-JoshuaKGoldberg" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-JoshuaKGoldberg" title="Maintenance">🚧</a> <a href="https://github.com/JoshuaKGoldberg/create-typescript-app/pulls?q=is%3Apr+reviewed-by%3AJoshuaKGoldberg" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/JoshuaKGoldberg/create-typescript-app/commits?author=JoshuaKGoldberg" title="Tests">⚠️</a> <a href="#tool-JoshuaKGoldberg" title="Tools">🔧</a></td>
-			    </tr>
-			  </tbody>
-			</table>
+							<!-- spellchecker: disable -->
+							<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
+							<!-- prettier-ignore-start -->
+							<!-- markdownlint-disable -->
+							<table>
+							  <tbody>
+							    <tr>
+							      <td align="center" valign="top" width="14.28%"><a href="http://www.joshuakgoldberg.com"><img src="https://avatars.githubusercontent.com/u/3335181?v=4?s=100" width="100px;" alt="Josh Goldberg"/><br /><sub><b>Josh Goldberg</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=author%3AJoshuaKGoldberg" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/create-typescript-app/commits?author=JoshuaKGoldberg" title="Code">💻</a> <a href="#design-JoshuaKGoldberg" title="Design">🎨</a> <a href="https://github.com/JoshuaKGoldberg/create-typescript-app/commits?author=JoshuaKGoldberg" title="Documentation">📖</a> <a href="#ideas-JoshuaKGoldberg" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-JoshuaKGoldberg" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-JoshuaKGoldberg" title="Maintenance">🚧</a> <a href="https://github.com/JoshuaKGoldberg/create-typescript-app/pulls?q=is%3Apr+reviewed-by%3AJoshuaKGoldberg" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/JoshuaKGoldberg/create-typescript-app/commits?author=JoshuaKGoldberg" title="Tests">⚠️</a> <a href="#tool-JoshuaKGoldberg" title="Tools">🔧</a></td>
+							    </tr>
+							  </tbody>
+							</table>
 
-			<!-- markdownlint-restore -->
-			<!-- prettier-ignore-end -->
+							<!-- markdownlint-restore -->
+							<!-- prettier-ignore-end -->
 
-			<!-- ALL-CONTRIBUTORS-LIST:END -->
-			<!-- spellchecker: enable -->",
-			        ],
-			      },
-			      "block": [Function],
-			    },
-			    {
-			      "addons": {
-			        "secrets": [
-			          {
-			            "description": "a GitHub PAT with repo and workflow permissions",
-			            "name": "ACCESS_TOKEN",
-			          },
-			        ],
-			      },
-			      "block": [Function],
-			    },
-			  ],
-			  "files": {
-			    ".all-contributorsrc": "{"badgeTemplate":"\\t<a href=\\"#contributors\\" target=\\"_blank\\"><img alt=\\"👪 All Contributors: <%= contributors.length %>\\" src=\\"https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-<%= contributors.length %>-21bb42.svg\\" /></a>","contributors":[{"avatar_url":"https://avatars.githubusercontent.com/u/3335181?v=4","contributions":["bug","code","design","doc","ideas","infra","maintenance","review","test","tool"],"login":"JoshuaKGoldberg","name":"Josh Goldberg","profile":"http://www.joshuakgoldberg.com"}],"contributorsSortAlphabetically":true,"projectName":"test-repository","projectOwner":"test-owner"}",
-			    ".github": {
-			      "workflows": {
-			        "contributors.yml": "jobs:
-			  contributors:
-			    runs-on: ubuntu-latest
-			    steps:
-			      - uses: actions/checkout@v4
-			        with:
-			          fetch-depth: 0
-			      - uses: ./.github/actions/prepare
-			      - env:
-			          GITHUB_TOKEN: \${{ secrets.ACCESS_TOKEN }}
-			        uses: JoshuaKGoldberg/all-contributors-auto-action@v0.5.0
+							<!-- ALL-CONTRIBUTORS-LIST:END -->
+							<!-- spellchecker: enable -->",
+							        ],
+							      },
+							      "block": [Function],
+							    },
+							    {
+							      "addons": {
+							        "secrets": [
+							          {
+							            "description": "a GitHub PAT with repo and workflow permissions",
+							            "name": "ACCESS_TOKEN",
+							          },
+							        ],
+							      },
+							      "block": [Function],
+							    },
+							  ],
+							  "files": {
+							    ".all-contributorsrc": "{"badgeTemplate":"\\t<a href=\\"#contributors\\" target=\\"_blank\\"><img alt=\\"👪 All Contributors: <%= contributors.length %>\\" src=\\"https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-<%= contributors.length %>-21bb42.svg\\" /></a>","contributors":[{"avatar_url":"https://avatars.githubusercontent.com/u/3335181?v=4","contributions":["bug","code","design","doc","ideas","infra","maintenance","review","test","tool"],"login":"JoshuaKGoldberg","name":"Josh Goldberg","profile":"http://www.joshuakgoldberg.com"}],"contributorsSortAlphabetically":true,"projectName":"test-repository","projectOwner":"test-owner"}",
+							    ".github": {
+							      "workflows": {
+							        "contributors.yml": "jobs:
+							  contributors:
+							    runs-on: ubuntu-latest
+							    steps:
+							      - uses: actions/checkout@v4
+							        with:
+							          fetch-depth: 0
+							      - uses: ./.github/actions/prepare
+							      - env:
+							          GITHUB_TOKEN: \${{ secrets.ACCESS_TOKEN }}
+							        uses: JoshuaKGoldberg/all-contributors-auto-action@v0.5.0
 
-			name: Contributors
+							name: Contributors
 
-			on:
-			  push:
-			    branches:
-			      - main
-			",
-			      },
-			    },
-			  },
-			  "scripts": [
-			    {
-			      "commands": [
-			        "pnpx all-contributors-cli add test-owner code,content,doc,ideas,infra,maintenance,projectManagement,tool",
-			      ],
-			      "phase": 3,
-			    },
-			  ],
-			}
-		`);
+							on:
+							  push:
+							    branches:
+							      - main
+							",
+							      },
+							    },
+							  },
+							  "scripts": [
+							    {
+							      "commands": [
+							        "pnpx all-contributors-cli add test-owner code,content,doc,ideas,infra,maintenance,projectManagement,tool",
+							      ],
+							      "phase": 3,
+							    },
+							  ],
+							}
+						`);
 	});
 });
diff --git a/src/blocks/blockCodecov.test.ts b/src/blocks/blockCodecov.test.ts
index 678df87..7f18bba 100644
--- a/src/blocks/blockCodecov.test.ts
+++ b/src/blocks/blockCodecov.test.ts
@@ -24,6 +24,18 @@ describe("blockCodecov", () => {
 			      },
 			      "block": [Function],
 			    },
+			    {
+			      "addons": {
+			        "badges": [
+			          {
+			            "alt": "🧪 Coverage",
+			            "href": "https://codecov.io/gh/test-owner/test-repository",
+			            "src": "https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage",
+			          },
+			        ],
+			      },
+			      "block": [Function],
+			    },
 			    {
 			      "addons": {
 			        "actionSteps": [
@@ -47,42 +59,54 @@ describe("blockCodecov", () => {
 		});
 
 		expect(creation).toMatchInlineSnapshot(`
-			{
-			  "addons": [
-			    {
-			      "addons": {
-			        "apps": [
-			          {
-			            "name": "Codecov",
-			            "url": "https://github.com/apps/codecov",
-			          },
-			        ],
-			      },
-			      "block": [Function],
-			    },
-			    {
-			      "addons": {
-			        "actionSteps": [
-			          {
-			            "if": "always()",
-			            "uses": "codecov/codecov-action@v3",
-			          },
-			        ],
-			      },
-			      "block": [Function],
-			    },
-			    {
-			      "addons": {
-			        "files": [
-			          ".github/codecov.yml",
-			          "codecov.yml",
-			        ],
-			      },
-			      "block": [Function],
-			    },
-			  ],
-			}
-		`);
+				{
+				  "addons": [
+				    {
+				      "addons": {
+				        "apps": [
+				          {
+				            "name": "Codecov",
+				            "url": "https://github.com/apps/codecov",
+				          },
+				        ],
+				      },
+				      "block": [Function],
+				    },
+				    {
+				      "addons": {
+				        "badges": [
+				          {
+				            "alt": "🧪 Coverage",
+				            "href": "https://codecov.io/gh/test-owner/test-repository",
+				            "src": "https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage",
+				          },
+				        ],
+				      },
+				      "block": [Function],
+				    },
+				    {
+				      "addons": {
+				        "actionSteps": [
+				          {
+				            "if": "always()",
+				            "uses": "codecov/codecov-action@v3",
+				          },
+				        ],
+				      },
+				      "block": [Function],
+				    },
+				    {
+				      "addons": {
+				        "files": [
+				          ".github/codecov.yml",
+				          "codecov.yml",
+				        ],
+				      },
+				      "block": [Function],
+				    },
+				  ],
+				}
+			`);
 	});
 
 	test("with addons", () => {
@@ -96,35 +120,47 @@ describe("blockCodecov", () => {
 		});
 
 		expect(creation).toMatchInlineSnapshot(`
-			{
-			  "addons": [
-			    {
-			      "addons": {
-			        "apps": [
-			          {
-			            "name": "Codecov",
-			            "url": "https://github.com/apps/codecov",
-			          },
-			        ],
-			      },
-			      "block": [Function],
-			    },
-			    {
-			      "addons": {
-			        "actionSteps": [
-			          {
-			            "env": {
-			              "CODECOV_TOKEN": "\${{ secrets.CODECOV_TOKEN }}",
-			            },
-			            "if": "always()",
-			            "uses": "codecov/codecov-action@v3",
-			          },
-			        ],
-			      },
-			      "block": [Function],
-			    },
-			  ],
-			}
-		`);
+			      	{
+			      	  "addons": [
+			      	    {
+			      	      "addons": {
+			      	        "apps": [
+			      	          {
+			      	            "name": "Codecov",
+			      	            "url": "https://github.com/apps/codecov",
+			      	          },
+			      	        ],
+			      	      },
+			      	      "block": [Function],
+			      	    },
+			      	    {
+			      	      "addons": {
+			      	        "badges": [
+			      	          {
+			      	            "alt": "🧪 Coverage",
+			      	            "href": "https://codecov.io/gh/test-owner/test-repository",
+			      	            "src": "https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage",
+			      	          },
+			      	        ],
+			      	      },
+			      	      "block": [Function],
+			      	    },
+			      	    {
+			      	      "addons": {
+			      	        "actionSteps": [
+			      	          {
+			      	            "env": {
+			      	              "CODECOV_TOKEN": "\${{ secrets.CODECOV_TOKEN }}",
+			      	            },
+			      	            "if": "always()",
+			      	            "uses": "codecov/codecov-action@v3",
+			      	          },
+			      	        ],
+			      	      },
+			      	      "block": [Function],
+			      	    },
+			      	  ],
+			      	}
+			      `);
 	});
 });
diff --git a/src/blocks/blockContributorCovenant.test.ts b/src/blocks/blockContributorCovenant.test.ts
index b5f8143..eec073e 100644
--- a/src/blocks/blockContributorCovenant.test.ts
+++ b/src/blocks/blockContributorCovenant.test.ts
@@ -12,6 +12,20 @@ describe("blockContributorCovenant", () => {
 
 		expect(creation).toMatchInlineSnapshot(`
 			{
+			  "addons": [
+			    {
+			      "addons": {
+			        "badges": [
+			          {
+			            "alt": "🤝 Code of Conduct: Kept",
+			            "href": "https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md",
+			            "src": "https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42",
+			          },
+			        ],
+			      },
+			      "block": [Function],
+			    },
+			  ],
 			  "files": {
 			    ".github": {
 			      "CODE_OF_CONDUCT.md": "# Contributor Covenant Code of Conduct
@@ -162,6 +176,18 @@ describe("blockContributorCovenant", () => {
 		expect(creation).toMatchInlineSnapshot(`
 			{
 			  "addons": [
+			    {
+			      "addons": {
+			        "badges": [
+			          {
+			            "alt": "🤝 Code of Conduct: Kept",
+			            "href": "https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md",
+			            "src": "https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42",
+			          },
+			        ],
+			      },
+			      "block": [Function],
+			    },
 			    {
 			      "addons": {
 			        "files": [
diff --git a/src/blocks/blockREADME.test.ts b/src/blocks/blockREADME.test.ts
index 287fd75..d38ea11 100644
--- a/src/blocks/blockREADME.test.ts
+++ b/src/blocks/blockREADME.test.ts
@@ -26,10 +26,6 @@ describe("blockREADME", () => {
 			<p align="center">One sentence.</p>
 
 			<p align="center">
-				<a href="https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
-				<a href="https://codecov.io/gh/test-owner/test-repository" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage" /></a>
-				<a href="https://github.com/test-owner/test-repository/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
-				<a href="http://npmjs.com/package/test-repository"><img alt="📦 npm version" src="https://img.shields.io/npm/v/test-repository?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
 				<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 			</p>
 
@@ -67,10 +63,6 @@ describe("blockREADME", () => {
 			</p>
 
 			<p align="center">
-				<a href="https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
-				<a href="https://codecov.io/gh/test-owner/test-repository" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage" /></a>
-				<a href="https://github.com/test-owner/test-repository/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
-				<a href="http://npmjs.com/package/test-repository"><img alt="📦 npm version" src="https://img.shields.io/npm/v/test-repository?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
 				<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 			</p>
 
@@ -105,10 +97,6 @@ describe("blockREADME", () => {
 			<p align="center">Test description</p>
 
 			<p align="center">
-				<a href="https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
-				<a href="https://codecov.io/gh/test-owner/test-repository" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage" /></a>
-				<a href="https://github.com/test-owner/test-repository/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
-				<a href="http://npmjs.com/package/test-repository"><img alt="📦 npm version" src="https://img.shields.io/npm/v/test-repository?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
 				<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 			</p>
 
@@ -149,10 +137,6 @@ describe("blockREADME", () => {
 			<p align="center">Test description</p>
 
 			<p align="center">
-				<a href="https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
-				<a href="https://codecov.io/gh/test-owner/test-repository" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage" /></a>
-				<a href="https://github.com/test-owner/test-repository/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
-				<a href="http://npmjs.com/package/test-repository"><img alt="📦 npm version" src="https://img.shields.io/npm/v/test-repository?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
 				<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 			</p>
 
@@ -194,10 +178,6 @@ describe("blockREADME", () => {
 			<p align="center">Test description</p>
 
 			<p align="center">
-				<a href="https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
-				<a href="https://codecov.io/gh/test-owner/test-repository" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage" /></a>
-				<a href="https://github.com/test-owner/test-repository/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
-				<a href="http://npmjs.com/package/test-repository"><img alt="📦 npm version" src="https://img.shields.io/npm/v/test-repository?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
 				<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 			</p>
 
@@ -240,10 +220,6 @@ describe("blockREADME", () => {
 			<p align="center">Test description</p>
 
 			<p align="center">
-				<a href="https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
-				<a href="https://codecov.io/gh/test-owner/test-repository" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage" /></a>
-				<a href="https://github.com/test-owner/test-repository/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
-				<a href="http://npmjs.com/package/test-repository"><img alt="📦 npm version" src="https://img.shields.io/npm/v/test-repository?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
 				<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 			</p>
 
@@ -280,10 +256,6 @@ describe("blockREADME", () => {
 			<p align="center">Test description</p>
 
 			<p align="center">
-				<a href="https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
-				<a href="https://codecov.io/gh/test-owner/test-repository" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage" /></a>
-				<a href="https://github.com/test-owner/test-repository/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
-				<a href="http://npmjs.com/package/test-repository"><img alt="📦 npm version" src="https://img.shields.io/npm/v/test-repository?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
 				<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 			</p>
 
@@ -305,7 +277,21 @@ describe("blockREADME", () => {
 	test("with addons", () => {
 		const creation = testBlock(blockREADME, {
 			addons: {
-				badges: ["<!-- badge! -->"],
+				badges: [
+					{
+						alt: "Badge Z",
+						src: "https://img.shields.io/badge/my_badge-000000",
+					},
+					{
+						alt: "Badge A",
+						src: "https://img.shields.io/badge/my_badge-000000",
+					},
+					{
+						alt: "Badge With Link",
+						href: "https://create.bingo",
+						src: "https://img.shields.io/badge/my_badge-000000",
+					},
+				],
 				notices: ["> Hello, world! 💖"],
 				sections: [`## Other\n\nHello!`],
 			},
@@ -320,11 +306,9 @@ describe("blockREADME", () => {
 			<p align="center">Test description</p>
 
 			<p align="center">
-				<!-- badge! -->
-				<a href="https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
-				<a href="https://codecov.io/gh/test-owner/test-repository" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage" /></a>
-				<a href="https://github.com/test-owner/test-repository/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
-				<a href="http://npmjs.com/package/test-repository"><img alt="📦 npm version" src="https://img.shields.io/npm/v/test-repository?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
+				<img alt="Badge A" src="https://img.shields.io/badge/my_badge-000000" />
+				<a href="https://create.bingo" target="_blank"><img alt="Badge With Link" src="https://img.shields.io/badge/my_badge-000000" /></a>
+				<img alt="Badge Z" src="https://img.shields.io/badge/my_badge-000000" />
 				<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
 			</p>