App reviews, troubleshooting, and recommendations
Hi everyone,
I got kind of fed up with paying $4/month for a Table of Contents in my blog that didn't look great and loaded external scripts.
So I made one here you can use for free: https://cardboardcathomes.com/blogs/behind-the-scenes/a-tool-to-add-a-table-of-contents-to-your-shop...
Follow the instructions & use the generator tool at the bottom to make your own.
It's pretty straightforward to use but here's a video for more details: https://www.youtube.com/watch?v=2dTviqOH8oA
You must be referencing the app Jump Links the only Table of Contents App available in the Shopify App store 🙂
We built the app due to frustration as well. We wanted a Table of Contents on our blog and there was literally no way to get it on our blog. So we built the app 🙂
The $4 price is due to Shopify requiring apps be hosted on independent servers. This means it loads fast and won't impact your site speed, but also costs money. Way more than $4 btw... Also the app is automated and extremely easy to use. There is also a very helpful development team on staff if there are issues 🙂 The app is customizable and matches the theme font, so no two Jump Links Table of Contents will look the same. That said, if you don't like the look you can change it 🙂
You may not be alone in thinking that $4 is a lot of money. We can explore lowering it, but after Shopify fees, development costs, customer service and server costs, we're not over here printing money...
$4 seems like a reasonable cost for an optional tool that benefits a site's SEO in many ways. Read more about the SEO benefits here: Benefits of a Clickable Table of Contents For Long Blog Posts On Shopify
My point is that $50/year is a lot to pay for a feature that took me a few hours to build (and I'm pretty rusty).
That's what my completely free tool Table of Contents generator here does.
I don't know why you're saying it's so fast when it requires loading additional files into a site. It doesn't matter how they're hosted when it's completely unnecessary.
If you wanted to build a well-designed app:
1. It would edit the blog files and inline the styles. The shopify api should support this: https://shopify.dev/api/admin/rest/reference/online-store/blog
2. It would periodically check to see if new blog posts were added instead of requiring manually running it.
3. Your independent server would maintain both edited and clean versions of each blog post to revert if something goes wrong.
Overall the shopify ecosystem has a long way to go. Apps like these have long been free for wordpress: https://wordpress.org/plugins/easy-table-of-contents/
Plak theme is the first to include the Table of content on their themes
Sorry I do not know how to add my own answer so I replied to yours, but yes I wanted to share this free Table of Contents generator. I hope this helps.
Sorry I didn't see this post earlier, you can use it for free if you install the EComposer app. Please see instructions here
Finally Easy Table of Content (REALLY), the right way: https://apps.shopify.com/easy-table-of-content
😉
Hi everyone,
RuffRuff Table of Contents is free enough to use.
I hope this helps.
I have published a super easy video on this topic. You may check this out.
Thanks a lot - you and chatgpt solved my problem for a free table of content for my impact-theme 🙂
maybe not perfect, but solved my problem even with doubled headings in the content list
for all other with the impact theme - buy Sakinur-Rahman a coffee 😉
<script>
document.addEventListener('DOMContentLoaded', function() {
// Get all 'h2' tags and 'p' tags with class 'h1 hyphenate' inside 'section'
const headings = document.querySelectorAll("section h2, section p.h1.hyphenate");
// Create a contents container
const contentsContainer = document.createElement('div');
contentsContainer.id = 'contents-container';
// Create a heading for the contents table
const contentsHeading = document.createElement('h3');
contentsHeading.textContent = 'Index';
// Create an unordered list for the contents
const contentsList = document.createElement('ul');
contentsList.id = 'contents';
// Append heading and list to the contents container
contentsContainer.appendChild(contentsHeading);
contentsContainer.appendChild(contentsList);
// Insert the contents container before the first heading tag
if (headings.length > 0) {
const firstHeading = headings[0];
firstHeading.parentNode.insertBefore(contentsContainer, firstHeading);
}
// Track added headings to avoid duplicates and to overwrite if necessary
const addedHeadings = {};
// Loop through each heading tag
headings.forEach((heading, index) => {
// Create a unique ID for each heading
const headingId = `heading-${index + 1}`;
// Check if this heading text already exists in the TOC
if (addedHeadings[heading.textContent]) {
// Remove the old entry from the TOC
const oldListItem = document.getElementById(addedHeadings[heading.textContent]);
if (oldListItem) {
oldListItem.parentNode.removeChild(oldListItem);
}
}
// Assign ID to the heading
heading.id = headingId;
// Create a list item for the contents table
const listItem = document.createElement('li');
listItem.id = headingId + '-item'; // Unique ID for the list item
// Create an anchor tag with a link to the corresponding heading
const anchor = document.createElement('a');
anchor.href = `#${heading.id}`;
anchor.textContent = heading.textContent;
// Append the anchor tag to the list item
listItem.appendChild(anchor);
// Append the list item to the contents table
contentsList.appendChild(listItem);
// Track the added heading
addedHeadings[heading.textContent] = listItem.id;
});
});
</script>
<style>
#contents-container {
background: #F3F9FF;
padding: 15px;
border-radius: 5px;
}
#contents-container a {
font-size: 16px;
line-height: 1.5;
text-decoration: none;
color: #333;
}
#contents-container a:hover {
text-decoration: underline;
}
#contents-container h3 {
margin: 0;
margin-bottom: 10px;
}
#contents-container ul {
padding: 0;
margin: 0;
list-style: none;
}
#contents-container li {
list-style-type: none;
margin-bottom: 5px;
}
html {
scroll-behavior: smooth;
}
</style>
ok had to rework a little but now it work (at least for me) 😉 - if not, it is a good starting point
<script>
//EW01_A_170524_Inhaltsverzeichnis
document.addEventListener('DOMContentLoaded', function() {
// Get all relevant header tags inside '.article-template'
const headerTags = document.querySelectorAll("section h2, .h1.hyphenate");
// Create a contents container
const contentsContainer = document.createElement('div');
contentsContainer.id = 'contents-container';
// Create a heading for the contents table
const contentsHeading = document.createElement('h3');
contentsHeading.textContent = 'Index';
// Create an unordered list for the contents
const contentsList = document.createElement('ul');
contentsList.id = 'contents';
// Append heading and list to the contents container
contentsContainer.appendChild(contentsHeading);
contentsContainer.appendChild(contentsList);
// Insert the contents container before the first header tag
const firstHeader = headerTags[0];
if (firstHeader) {
firstHeader.parentNode.insertBefore(contentsContainer, firstHeader);
}
// Loop through each relevant header tag
headerTags.forEach((header, index) => {
// Skip hidden headers
//if (header.closest('.hidden') || header.closest('.md\\:hidden')) return;
if (header.closest('.md\\:hidden') || header.textContent.trim().toLowerCase() === '. . .' ) return;
// Assign ids to header tags
header.id = `header-${index + 1}`;
// Create a list item for the contents table
const listItem = document.createElement('li');
// Create an anchor tag with a link to the corresponding header tag
const anchor = document.createElement('a');
anchor.href = `#${header.id}`;
anchor.textContent = header.textContent;
// Append the anchor tag to the list item
listItem.appendChild(anchor);
// Append the list item to the contents table
contentsList.appendChild(listItem);
});
});
//EW01_E_170524_Inhaltsverzeichnis zusätzlich untere Style Bedingung
</script>
<style>
#contents-container {
background: #F3F9FF;
padding: 15px;
border-radius: 5px;
}
#contents-container a {
font-size: 16px;
line-height: 1.5;
}
#contents-container h3 {
margin: 0;
margin-bottom: 10px;
}
#contents-container ul {
padding: 0;
margin: 0;
padding-left: 15px;
}
#contents-container li {
list-style-type: none; /* Entfernt den Marker */
}
html {
scroll-behavior: smooth;
}
</style>
Hi @wucash
Glad that it helped you and thanks so much for sending two Coffees.
page not found! Can you please reshare the link for the app?
In your main-article.liquid file (in Dawn, not sure on other themes), above the schema section add this code .. it will transform all H2 links into a TOC item, and insert the entire TOC above the first H2.
##########################################
By investing 30 minutes of your time, you can unlock the potential for increased sales,...
By Jacqui Sep 11, 2024We appreciate the diverse ways you participate in and engage with the Shopify Communi...
By JasonH Sep 9, 2024Thanks to everyone who participated in our AMA with 2H Media: Marketing Your Shopify St...
By Jacqui Sep 6, 2024