Add a Custom Pinterest Button to your Website (Part 2)

Jeremy Mansfield
January 10, 2013

When I started out searching for a global solution with a “one and done” approach to placing  Pinterest’s “pin it” button on a page and wrote about it in this post, I didn’t quite expect the sheer volume of responses from users out there searching for the same thing. I was even more pleasantly surprised when one of our readers took the time to make this even better and provided a write-up on what he discovered.

Thanks to Cameron Clark, I’d like to offer you a follow up (alternate) solution to the original article I posted here.

 

Background

Like many developers, Cameron wanted to give his visitors the ability to pin a variety images from his site to their Pinterest boards. For a little background re-cap, on the Pinterest site, when you enter a URL to pin, it collects all the images from the webpage and allows you to choose which one you want to pin. Pinterest also provides a very clever bookmarklet code that you can add to your browser to do the same thing from whatever webpage you’re currently on.

But if you use Pinterest’s official code to add a “pin it” button to your webpage, you have no such ability—you have to pre-select the image for the user to pin. The code looks something like this:

<a href="http://pinterest.com/pin/create/button/?url=yourpageurl.html&amp;media=yourimgurl.html&amp;description=yourdescriptiontext" target="_blank" count-layout="none"><img border="0" src="pin-it-button.png" title="Pin It"></a>

This seems unintuitive and rather limiting. Lots of other developers have been frustrated by this too, and have discovered a solution: call the Pinterest bookmarklet.js code from your website, which seems to work great.

But when the JavaScript code was thoroughly examined, the inefficiency of this method became very evident. The bookmarklet code is structured as a self-executing anonymous JavaScript function, which simply means that it runs immediately after you load the file—and in fact that’s the only way to run it. So every time somebody clicks the “pin it” button, you have to load the JavaScript file, even if it’s already been loaded. Furthermore, this file was being retrieved with a randomly-generated number added to the end of the URL to prevent caching. At 24 Kb, it’s a good-sized file. On a fast Internet connection, this may take only a fraction of a second, but on slower connections, such as the data network on your phone or tablet, this is a significant amount of data to load. And it just seemed crazy to prevent the file from being cached.

The Pinterest team was contacted to ask if they had a better solution. You would think they might have a variation on their bookmarklet.js code for use on individual websites. And since the bookmarklet code resides on their servers, and that’s where everybody’s calling it from, seems like they would want to provide a better solution to reduce needless traffic on their servers. Pinterest failed to respond.

 

Solution

Cameron was able to go through the bookmarklet.js code and tried to make it more flexible and efficient. While not fully understanding everything Pinterest was trying to do, here is a variation on their code that will hopefully be a little simpler to use and more efficient.

Sample: http://www.brandaiddesignco.com/tutorials/pinterest/

Script: http://www.brandaiddesignco.com/tutorials/pinterest/pinimages.js (or minifed: http://www.brandaiddesignco.com/tutorials/pinterest/pinimages.min.js)

First it was converted from a self-executing anonymous function to a function named selectPinImage(). Once the script is loaded, call this function whenever the “pin it” button is pressed.

The script can be loaded in a regular <script> tag, then the selectPinImage() can be called:

<script type="text/javascript" src="pinimages.js"></script>
 <a href="javascript:selectPinImage()"><img border="0" src="pin-it-button.png" title="Pin It"></a>

Or the script can be loaded dynamically when the pin it button is pressed. Here’s an xample with JQuery:

<a href="javascript:$.getScript("pinimages.js", function() { selectPinImage() })"><img border="0" src="pin-it-button.png" title="Pin It"></a>

Either way, the script file should cache after it’s first loaded.

Ideally, you should use this code in conjunction with the standard Pinterest code which specifies an preselected image. That way, if the JavaScript fails for some reason, the “pin it” button still works, but just doesn’t let you select an image. Example:

<script type="text/javascript" src="pinimages.js"></script>
 <a href="http://pinterest.com/pin/create/button/?url=yourpageurl.html&amp;media=yourimgurl.html&amp;description=yourdescriptiontext" target="_blank" count-layout="none" onclick="selectPinImage(); return false"><img border="0" src="pin-it-button.png" title="Pin It"></a>

The revised version of the script seems to work fine in IE 7 and IE8. It’s unclear what the issue was preventing the original version from working in those browsers.

For the description for the pinned image, the original version of the script grabs any text that the user has selected on the page, the alt or title attributes of each image, or a prefined ‘pinDesc’ value (in that order). The ability has been added to specify text to be dropped in before or after the pin description. (For example, you could append the HTML page title.) You can specify it like this:

selectPinImage('text to add before the pin description','text to add after');

Original version checks elements for display:none or visibility:hidden and excludes them, so you could only pin images that are visible. In addition, in IE only, elements that are effectively not visible—because a parent element was not visible—were also excluded because invisible elements have no width or height in IE. (This is an issue with pages on a site that are tabbed, and images on any tab except the currently visible one are excluded. Also excluded are any images in JavaScript-based slideshows that aren’t visible at the exact moment the script runs.) For consistency between browsers, code was added that checks more rigorously to see if an element is actually visible. An optional parameter was also added to the function to specify whether you want hidden elements included in the pin list or not. It defaults to not including hidden elements. Below is an example of how to make hidden elements pinnable:

selectPinImage('text to add before the description','text to add after',true);

The original version collects pinnable elements from the entire page. Further added was the ability to specify an element within the page and to only gather pinnable elements from that. Example:

selectPinImage('text to add before the description','text to add after',document.getElementById('pageContent'));

Also added is the ability to define which HTML elements to collect for pinning. Defaults to “meta”, “iframe”, “embed”, “object”, “img”, “video”, “a”. But you could limit this list to, say, just “img” tags:

selectPinImage('text to add before the description','text to add after',document.getElementById('pageContent'),['img']);

The original function checked the page for a PINTEREST=NOPIN meta tag, and popped up an error message if it was found and exited. This seemed pointless since you wouldn’t add this to any page from which you didn’t want to pin things from, so it was removed.

The original function excludes any elements with the attribute nopin=”nopin”. This seemed useful, so it was left in.

 

Conclusion

Whew! So there you have it. Again, a big hearty thanks to Cameron Clark for taking the time to digest the problem and come up with a viable solution!

Happy pinning, and click here to read the first edition of this article.

13 Comments
Kristen
January 24, 2013

Sorry, but what is the final code in it’s entirety then that should be used?


Kate
January 27, 2013

Thank you so much for this post, this is getting me very close to what I need to do, but I have one question.

I used the “a” tag from your sample site pulling images from a div with a certain id and that’s working great and I can get my own description in there, but I don’t know how to set a specific url. I have a page of many products, and each product has its own link to that area of the page (like “mysite.com/products.php#product1” so I’d like to be able to have each pinit button on the page (there are several) next to each product pass a certain link. I love that each pinit button can pull just the images related to that particular product on the page, but I need it to also go back to that particular link. How can I do that?


Jeremy Mansfield
January 31, 2013

Hi Kristin, the first two code snippets at the top in the “Solution” section are both usable for this new example. You can also check out the html in the example links referenced and strip from there.


Jeremy Mansfield
January 31, 2013

Hi Kate, I’ll have to do a little research at the moment. I don’t think our solution is intended for that chief result. It seems that’s more of the intention of the original function provided by Pinterest themselves.


Jeff Carter
March 15, 2013

Hi Jeremy,

Thanks for pulling all this together and taking the time to post it here. I have had great success implementing it on our site, but an issue has come up that is specific to ie9. After triggering the script, the pinterest widow opens but the thumbnail does not resolve (even though the image dimensions are captured). The script must be pulling the thumbnail correctly because when you hover and pin the blank tile, things carry on as they should. Again, everything is fine in Chrome/Firefox/Safari.

Have you run into this, and is there an implementation parameter I’m neglecting?

The button is at the bottom of posts on our blog: http://www.rockbrookcamp.com/blog/


Jeremy Mansfield
March 15, 2013

Jeff, I’m not sure why you’re experiencing the problem in IE9. You might check out our first article on this and revert to that method as it does work in IE9 for us: http://www.brandaiddesignco.com/insights/add-a-custom-pinterest-pin-it-button-to-your-website/375/


Jeff Carter
March 18, 2013

Hmmm… I’ve now tried the original method and I’m experiencing the same issue in IE9. I can get things to work when in “Compatibility View,” but not otherwise. Other ideas?


Jeremy Mansfield
March 18, 2013

Thanks for reaching out to Cameron. Glad he was able to help figure out what was wrong in your stylesheet declarations.


Jeff Carter
March 19, 2013

A quick update to share what was causing the trouble with the script in IE9… Our site’s style.css was declaring ‘img { height:auto;}’ and for some reason caused IE9, when running the Pinterest javascript, to assign images on the page a width=0. Hence the blank thumbnails in the script. Removing that image height declaration fixed everything. Sweet success! Thanks to Cameron for figuring this out.

This script is fantastic!


Robert Samnegård
March 29, 2013

Custom URL solved!

First, Jeremy & Cameron, let me thank you very much for this post!

I have solved the “problem” with custom URL. I’m not an expert on JavaScript at all so this must be considered as a hack! 🙂

Instructions:

1. Edit row 4 and add parameter “ownUrl”:

/* Based on Pinterest bookmarklet code from http://assets.pinterest.com/js/pinmarklet.js
Modified by Cameron Clark
Modified again by Robert Samnegård regarding Custom URL-support
*/
function selectPinImage(prepend, append, hidden, within, ownUrl, elements) {

2. Add row after “appendText” (row 26):

ownUrlText: ownUrl || ”,

3. Search for “&url” (row 275) and you will find a “g” on that row. Change the whole row to:

c = c + “&url=” + encodeURIComponent(a.a.ownUrlText);

Finally, pass your own URL in the link that runs the JS:

I’m not sure if there is any issues regarding the code changes above. If you find anything, please comment here.

I have searched the web a lot to find a solution to this problem. Thanks to you guys, Jeremy & Cameron, there now is!

I use the code to make it possible to pin directly on a multi-post page such the blog part of WordPress.

You can check the code in action at http://studio-gul.se/blogg/

/Robert – Sweden


Jeremy Mansfield
March 29, 2013

Thanks for posting your findings, Robert!


Joy
May 22, 2013

Thank you! I’ve been wondering how to do this, and it works great 🙂


Lee
September 3, 2013

I’m a newb at this so I apologize if the answer to my question is staring at me in the face….I only want to make one image on my page pinnable out of a possible 4; all images are being selected for pinning when I implement the code (on the plus side the code works perfectly so big thanks for that!)


Work With Us?