twee+: Longer tweets, no strings attached

As some people that have been following me for a while know, the 140 character limit on twitter bugs me a lot sometimes, and I’ve tried to find a way to overcome it previously as well. The most common ways these days seems to be either cutting down the long tweet into multiple pieces (yuck) or using a service to host the longer tweet and post a summary with a link to it.

The latter isn’t an entirely horrible option. However, I see 3 big downsides:

  1. I’m not very comfortable with the idea of some external service hosting my content which could close down any time due to failure to monetize their website. In that case, I’d be left with some dead links that are of no value and my content would be lost forever. Yes, they usually warn you in advance in such cases, but such news could be missed for a number of reasons.
  2. People (including yours truly) don’t plan those things in advance. They just seek services like that at the exact moment when they want to post a long tweet. Being greeted with a prompt to use Twitter Connect is NOT nice. For starters, it slows me down. Also, I don’t want to give permission to every website on the effing interwebs to post on my twitter timeline. I owe it to my followers to be responsible and not risk filling their timelines with crap.
  3. Most of these websites look like someone puked and what came out happened to be HTML and CSS. The only exception I’ve found is twtmore, but it still suffers from #1 and #2.
So, like every developer with a healthy amount of NIH syndrome, I decided to write my own :D
My goals were:
  1. It had to be entirely client-side (except initially getting downloaded from the server of course). This way, whoever is concerned can download the full website and decode their tweets with it if it ever goes down. Also, being entirely client side allows it to scale very easily, as serving files is not a very resource intensive job (compared to databases and the like).
  2. No Twitter Connect, the tweets would get posted through Twitter Web Intents.
  3. It had to look good. I’m not primarily a designer, so I can’t make something that looks jaw-droppingly amazing, but I can at least make it look very decent.
  4. If I was gonna go through all the hassle of making this, I may as well try to keep it under 10K, so that I could take part in the 10K apart contest. (I haven’t submitted it yet, I’ll submit a few days before the deadline, as it seems you can’t make changes to your submission and I want to polish the code a bit, especially the JS — I’m not too proud about it)
I managed to succeed in all my goals and I really liked the result. I ended up using it for stuff I never imagined, like checking if a twitter username corresponds to the account I think (as it shows the avatars). So I went ahead and came up with a name, bought a domain for it, and tweeplus.com was born :)

twee+? Seriously?

Yes, I like it. The plus means “more”, which is fitting and + kinda looks like a t, so it could be read as “tweet” as well. Yes, I know that the word “twee” has some negative connotations, but oh well, I still like the name. Whoever doesn’t can just not use it, I won’t get depressed, I promise. :P

Geeky stuff

How it works

  • A relatively new feature, Twitter automatically wraps URLs in t.co links, making them only 20 characters long.
  • All the text of the tweet is stored in the URL hash (query string will also work, although the output uses a hash). Some research revealed that actually browsers can handle surprisingly long URLs. Essentially, the only limit (2083 characters) is enforced by Internet Explorer. I decided to limit tweets to 2000 characters (encoded length), not only because of the IE limit, but also because I wouldn’t like people to post whole books in t.co links. We don’t want Twitter to start taking measures against this, do we? :)
  • A hard part was deciding which encoding to use (twitter is quite limited in the characters it parses as part of a URL).
    • My first thought was base64, but I quickly realized this was not a very good idea:
      • The encoding & decoding functions (btoa() and atob() respectively) are relatively new and therefore not supported by older browsers. I’m fine with the app hardly working in old browsers, but existing links must as a minimum be readable.
      • It uses approximately 1.34 characters per ASCII character. Unicode characters need to be URL-encoded first, otherwise an Exception is thrown. URL-encoding them uses 6 characters, which would result in 8 characters when they’re base64 encoded.
    • Then I thought of using URL-encoding for the whole thing. The good thing with it is that for latin alphanumeric characters (which are the most) it doesn’t increase the string length at all. For non-alphanumeric characters it takes up 3 characters and 6 characters for Unicode ones. Also, it’s much more readable.
    • Still, implementing it was tricky. It doesn’t encode some characters (like the dot), even though twitter doesn’t accept them as part of a URL. Also, escape() and encodeURI() behave differently and the Unicode encoding returned by the former isn’t accepted by Twitter. So I had to combine the two and do some substitutions manually.
  • When the textarea changes, the hash does too. The whole thing is a form with action=”http://twitter.com/intent/tweet”, so submitting it does the right thing naturally. I keep a hidden input with the tweet and the textarea has no name, so it doesn’t get submitted.
  • Usernames, hashtags and URLs get extracted and linkified. Usernames also get an avatar (it’s dead easy: Just use twitter.com/api/users/profile_image?screen_name={username} where {username} is the user’s username)
  • Internal “pages” (like “About” or “Browser support”) are essentially long “tweets” too.
  • A little easter egg is that if the browser supports radial gradients, the gradient follows the mouse, creating a spotlight effect. This looks nice on Chrome and Firefox, and really shitty on IE10, probably due to bugs in the gradient implementation (which I have to reduce & report sometime).

Buzzword compliance

This little app demonstrates quite a lot new open web technologies (HTML5, CSS3 etc), such as:

  • textarea maxlength
  • placeholder
  • autofocus (edit: I had to remove it cause it triggered a Webkit bug in Safari)
  • required inputs
  • New input types (url)
  • History API
  • oninput event (with keyup fallback)
  • hashchange event
  • SVG
  • Common CSS3 (border-radius, shadows, transitions, rgba, media queries)
  • CSS3 gradients
  • CSS3 animations
  • CSS3 resize
  • :empty
Let me know if I forgot something.
Oh yeah, I did forget something. There it is: twee+
  • Anonymous

    Nice work! :)
    Opened my mind to think of solutions that are right in front of us.Cheers,Rafael Caricio

  • http://mathiasbynens.be/ Mathias Bynens

    Nice! :)

    FYI, there’s also Hashify.me that does something similar: http://hashify.me/IyBUaXRsZQ==

  • http://blog.cherouvim.com/ Ioannis Cherouvim

    Really nice. Bravo.

  • http://profiles.google.com/addyosmani Addy Osmani

    As Mathias mentions, Hashify.me also does something similar, but great effort!. To me the only downside is prolly the arbitrary limit on characters, however if your needs are within that I guess it’s not an issue :)

    What a few of us have found helpful is opting to use Google Plus for longer tweets or micro-blogs. It’s an excellent platform for achieving this and also handles your data-lockin/loss concerns as you can export almost all the information on plus via ‘takeout’.  

    At the end of the day you are still going to need to have some sort of external link to view the rest of the content (as I notice your solution does too), but I’m sure it comes down to personal preference!.

  • http://blog.end3r.com/ Ender

    Beside the 10K Apart contest, You can submit it to the Mozilla Dev Derby too, as in august it’s all about the History API.

    Anyway, great app, especially when you check the list of new tech stuff applied!

  • http://twitter.com/necolas Nicolas Gallagher

    Hey Lea, one thing I noticed is that every addition/deletion of a character is stored in the browser history. Meant that I couldn’t use “back” (in practical terms) to return to this blog post.

    • http://leaverou.me Lea Verou

      I know :( I can’t really think of a way to work around this however, if you can, it’s welcome.

      • http://mathiasbynens.be/ Mathias Bynens

        Perhaps having the user press a button before changing the URL could be a solution? I do something similar for http://mothereffingcssescapes.com/ etc. and it works fine (doesn’t bother me I have to click first in order to get a permalink).

        • http://leaverou.me Lea Verou

          What I like about it is how quick it is to get the URL, this would disrupt that.

          An idea would be to change the URL whereever the textarea loses focus. I guess it does when somebody focuses on the URL bar, right?

        • http://leaverou.me Lea Verou

          Just did that. Hope you like how it works more now :)

  • http://www.webz.gr lexx

    Cool idea. I would definitely use it. Why file storage over db storage is better in terms of performance?

    • http://leaverou.me Lea Verou

      Services that use a database ALSO have static files. So it’s not one vs the other, it’s one and the other vs just the one. :)

  • Michael Butler

    Bravo! I love how the long tweet is stored in the URL, so if the website somehow went down in the future, you can still roughly access the tweet’s data. I just “tweeted” the first 3 paragraphs of Alice in Wonderland: 1300 characters.

  • http://floatboth.com MyFreeWeb

    Really good for you… No database to pay for :-) For users, I don’t think many would prefer this over twtmore. (Maybe for the awesome spotlight effect?)

    But I see it’s really good for Twitter client developers. Twtmore has an API. This doesn’t even need one, just construct a URL. Brilliant!

  • http://dan.cx/ Daniel15

    “I’m not primarily a designer, so I can’t make something that looks jaw-droppingly amazing”
    Are you kidding?! Your blog (and Twee+) do look amazing! You’re awesome. :)

    • http://leaverou.me Lea Verou

      Thank you! However, when I see what other designers are capable of, well I don’t think I’ll ever reach that level of visual creativity. I think my talent lies in code. Any design skill I might have is acquired and not innate.

      • http://dan.cx/ Daniel15

        I understand what you mean. Your designs are still awesome though! It’s quite rare to see someone that can do both coding *and* design – It usually seems to be just one or the other. I’m someone that can code but can’t design, and I know a lot of people that can design really well but can’t code anything other than very basic HTML and CSS. I’d love to reach your level of design skill one day, even if you think it’s not very much. :)

  • http://twitter.com/bonejp giannis

    Nice work
    really impressed with its simplicity

  • Whatisthisthingyoucallauth

    You’re a great designer, but your site manages to make surf (WebkitGtk) lag half a sentence after my typing on my Core 2 Duo rank as the second greatest memory hog, after Thunderbird. And that’s with me having to stop after half a sentence and check for typos. Is there such thing as too much style?
    Or maybe it’s all leaks from http://mediaqueries.es/?

    • http://leaverou.me Lea Verou

      I’m planning to add an option to turn the bling off, for such rare cases of lazy browsers.

  • http://www.thewebq.com Theodore Vorillas

    Really great work as usual:) Go for it for the 10k, I’ll also try to make something good
    PS. The color changing and the dots trip me after a big cup of coffee (or maybe 2 :P )

  • http://patik.com/ Craig Patik

    Is there any chance of a simple API? I have my own Twitter client and I’d love to be able to call [tweeplusURL]&format=json or [tweeplusurl]&callback=myFunction to grab the basic tweet info (username, the message itself, date, reply info).

  • http://patik.com/ Craig Patik

    Is there any chance of a simple API? I have my own Twitter client and I’d love to be able to call [tweeplusURL]&format=json or [tweeplusurl]&callback=myFunction to grab the basic tweet info (username, the message itself, date, reply info).

    • http://leaverou.me Lea Verou

      Most of the data you want aren’t stored, due to the nature of how it works. You can decode the URL by using the functions in api.js. No need for an API.

  • http://twitter.com/peterbata Peter Batah

    Efxaristo

  • http://assadotcom.blogspot.com/ assadotcom

    Awesome!!! Like This.
    @LeaVerou:disqus  Can I convert twee+ to blogger? if you permit, I will convert it. Thanks.

  • Juliette Ruth

    Cool! Funny thing is that in August 2011 I had a similar idea, but ended up with a completely different solution. (see: http://j.mp/JKGkt9 )

  • http://twitter.com/ColinEberhardt Colin Eberhardt

    You’re awesome. That is all :-)

  • tweetface_co

    Try http://www.tweetface.co – lets you do long tweets with rich text, images and video; creates personal blog of tweets.

  • http://tomercohen.com Tomer Cohen

    You could use some extra functionality by integrating few extra metadata into the HTML file that Twitter could use to show the user more information about the tweet.

    Twitter retreive links on publishing time, and maybe pull it again on a yet unknown interval, and you can feed Twitter with some information on the service you provide. Yes, it could be a bit difficult to provide the whole tweet in the summary as Twitter doesn’t seems to execute client-side code on their retrieval procedure, so a static description might be the most useful option.

    https://dev.twitter.com/docs/cards

  • http://raydere2.tumblr.com/ Raydere

    twee+ seems to have gone offline. Is the project kaput? I loved using it for long tweets. :(