Re: How to add a Table of Contents for your Blog Posts

How to add a Table of Contents for your Blog Posts

cardboardcat
Tourist
3 0 6

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

 

Replies 15 (15)

ATSuccess
New Member
4 0 0

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

cardboardcat
Tourist
3 0 6

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/

CodingLover
Shopify Partner
56 2 18

Plak theme is the first to include the Table of content on their themes

hazelseo
Visitor
2 0 0

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.

EComposer
Shopify Partner
2 0 0

Sorry I didn't see this post earlier, you can use it for free if you install the EComposer app. Please see instructions here

=================

Install EComposer: https://apps.shopify.com/ecomposer
Read More Detail: https://ecomposer.io/blogs/news/how-to-add-a-table-of-contents-to-your-shopify-article-blog-free-tool
Follow Us on Facebook: https://www.facebook.com/ecomposer.builder
Join Official Community: https://www.facebook.com/groups/ecomposer

Oukside
New Member
4 0 0

Finally Easy Table of Content (REALLY), the right way: https://apps.shopify.com/easy-table-of-content

 

😉

kyoshi_株式会社Tsun
Shopify Partner
209 73 49

Hi everyone,

 

RuffRuff Table of Contents is free enough to use.

 

I hope this helps.

株式会社Tsun
RuffRuff 注文制限RuffRuff 予約販売など6つのShopifyアプリを提供中 / おすすめ Shopifyアプリおすすめ 予約販売アプリなどShopify関連情報も発信中
株式会社TsunはShopifyストアの構築からグロース支援まで行うコマースソリューションパトナーです。

Wesley9
Excursionist
62 1 6
hazelseo
Visitor
2 0 0
Yup, found that months ago. Thanks.

sakinur-rahman
Shopify Partner
136 17 21

I have published a super easy video on this topic. You may check this out.

 

Need a Shopify developer? Chat on WhatsApp


- For Shopify Design Changes | Shopify Custom Coding | Custom Modifications -

Your Coffee Tip and my code, A perfect blend. ❤️ Buy Me A Coffee


Website: HelloSakin.com
wucash
Visitor
2 0 1

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>

wucash
Visitor
2 0 1

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>

sakinur-rahman
Shopify Partner
136 17 21

Hi @wucash 

Glad that it helped you and thanks so much for sending two Coffees.

Need a Shopify developer? Chat on WhatsApp


- For Shopify Design Changes | Shopify Custom Coding | Custom Modifications -

Your Coffee Tip and my code, A perfect blend. ❤️ Buy Me A Coffee


Website: HelloSakin.com

AbdulHadiecom
Tourist
6 0 0

page not found! Can you please reshare the link for the app?

ChrisDip
Shopify Partner
4 0 3

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.
##########################################

<script>
document.addEventListener('DOMContentLoaded', function() {
 // Get all 'h2' tags inside '.article-template'
    const h2Tags = document.querySelectorAll('article h2');
 
    // 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 = 'Table of Contents';
 
    // 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 'h2' tag
    const firstH2 = h2Tags[0];
    firstH2.parentNode.insertBefore(contentsContainer, firstH2);
 
    // Loop through each 'h2' tag
    h2Tags.forEach((h2, index) => {
        // Assign ids to 'h2' tags
        h2.id = (index + 1).toString();
 
        // Create a list item for the contents table
        const listItem = document.createElement('li');
 
        // Create an anchor tag with a link to the corresponding 'h2' tag
        const anchor = document.createElement('a');
        anchor.href = `#${h2.id}`;
        anchor.textContent = h2.textContent;
 
        // Append the anchor tag to the list item
        listItem.appendChild(anchor);
 
        // Append the list item to the contents table
        contentsList.appendChild(listItem);
    });
  
});
</script>
<style>
#contents-container {
background: #F3F9FF;
padding: 15px 15px 15px 15px;
border-radius: 5px;
}
#contents-container a {
font-size: 16px;
line-height: 1;
}
#contents-container h3 {
margin: 0;
margin-bottom: 10px;
}
#contents-container ul {
padding: 0;
margin: 0;
padding-left: 15px;
}
#contents-container li {
list-style: disclosure-closed;
}
html {
scroll-behavior: smooth;
}
</style>