Embed Tweets in an iframe - https://tf.rita.moe
1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>twitframe</title> 7 <meta name="description" content="Embed Tweets in an iframe"> 8 <style> 9 body { 10 font-family: helvetica neue, arial, helvetica, sans-serif; 11 font-size: 10pt; 12 margin: 1em auto; 13 max-width: 760px; 14 } 15 16 h1 { 17 margin: 0; 18 } 19 20 a { 21 color: #0000dd; 22 } 23 24 code, 25 pre { 26 background-color: #f2f2f2; 27 display: block; 28 margin: 1em auto; 29 outline: 1px solid #bbb; 30 overflow-x: auto; 31 padding: 1em; 32 } 33 34 div.iframe, 35 iframe { 36 font-family: serif; 37 font-size: 12pt; 38 margin-left: 1em; 39 } 40 41 div.iframe { 42 background-color: #fafafa; 43 height: 250px; 44 overflow-x: auto; 45 padding: 1em; 46 width: 550px; 47 } 48 49 div.iframe, 50 iframe.gray { 51 background-color: #fafafa; 52 } 53 54 tt { 55 color: green; 56 } 57 58 hr { 59 border: 1px solid gray; 60 } 61 </style> 62</head> 63<body> 64 <h1>twitframe</h1> 65 66 <p> 67 twitframe allows one to display 68 <a 69 href="https://developer.x.com/en/docs/x-for-websites/embedded-tweets/overview" 70 rel="noopener noreferrer" 71 target="_blank" 72 >Embedded Tweets</a> on websites to dynamically show retweet and favorite counts, inline media/card data, 73 and allow users to retweet/reply/favorite Tweets, all while isolating the Javascript and DOM manipulation in an <tt>iframe</tt>. 74 This increases security and speeds up website page loads. 75 </p> 76 77 <p style="color: gray; font-style: italic;"> 78 This is an independent service not affiliated with Twitter in any way. 79 No guarantee of availability or security is made by using this service. 80 </p> 81 82 <p style="color: gray; font-style: italic;"> 83 You're currently browsing a version of twitframe hosted by <strong>Rita.moe</strong>, with slight modifications to the original code. 84 </p> 85 86 <h3>Use</h3> 87 88 <p> 89 Add an <tt>&lt;iframe&gt;</tt> to your HTML document and pass (at least) the full URL to the Tweet as a 90 <a 91 rel="noopener noreferrer" 92 target="_blank" 93 href="https://en.wikipedia.org/wiki/Percent-encoding" 94 >URL-encoded</a> parameter <tt>url</tt> to <tt>http://tf.rita.moe/show</tt>: 95 </p> 96 97 <p> 98 <code> 99 &lt;iframe border="0" frameborder="0" height="250" width="550"<br> 100 &nbsp;src="https://tf.rita.moe/show?<span style="color: green;">url=https%3A%2F%2Ftwitter.com%2Fjack%2Fstatus%2F20</span>"&gt;<br> 101 &lt;/iframe&gt; 102 </code> 103 </p> 104 105 <p> 106 This example code would produce the following (without the gray background): 107 </p> 108 109 <iframe 110 border="0" 111 class="gray" 112 frameborder="0" 113 height="300" 114 src="https://tf.rita.moe/show?url=https%3A%2F%2Ftwitter.com%2Fjack%2Fstatus%2F20" 115 width="550" 116 ></iframe> 117 118 <p> 119 Note that a height of 300 may be too big for short tweets such as this one, but too small for long tweets with embedded media. 120 See <a href="#sizing">sizing</a> below to automatically size the <tt>iframe</tt> based on its size. 121 </p> 122 123 <p> 124 <h3>Graceful Degredation</h3> 125 </p> 126 127 <p> 128 If the Tweet data is known beforehand, it can be passed to twitframe to be displayed before Twitter's Javascript loads. 129 The following parameters may be passed: 130 </p> 131 132 <p> 133 <ul> 134 <li><tt>tweet</tt> - The full text of the Tweet</li> 135 <li><tt>author_name</tt> - The full name of the Tweet's author</li> 136 <li><tt>author_username</tt> - The username of the Tweet's author, including the @ sign</li> 137 <li><tt>datetime</tt> - The date and time of the Tweet, in ISO 8601 format or a Unix timestamp</li> 138 </ul> 139 </p> 140 141 <p> 142 Each parameter should be properly URL-encoded when used as the URL for the iframe. An example using PHP: 143 </p> 144 145 <p> 146<pre> 147&lt;?php 148 $tf = "https://tf.rita.moe/show?" . http_build_query(array( 149 "url" =&gt; "https://twitter.com/jack/status/20", 150 "tweet" =&gt; "just setting up my twttr", 151 "author_name" =&gt; "Jack Dorsey", 152 "author_username" =&gt; "jack", 153 "datetime" =&gt; "1142974214", 154 )); 155 156 echo "&lt;iframe border=\"0\" frameborder=\"0\" height=\"250\" width=\"550\" " 157 . "src=\"" . $tf . "\"&gt;&lt;/iframe&gt;"; 158?&gt; 159</pre> 160 </p> 161 162 <p> 163 If Twitter's Javascript could not be loaded, this example would produce the following (without the gray background): 164 </p> 165 166 <p> 167 <iframe 168 border="0" 169 class="gray" 170 frameborder="0" 171 height="300" 172 src="https://tf.rita.moe/show?url=https%3A%2F%2Ftwitter.com%2Fjack%2Fstatus%2F20&tweet=just+setting+up+my+twttr&author_name=Jack+Dorsey&author_username=jack&datetime=1142974214&force_fail=1" 173 width="550" 174 ></iframe> 175 </p> 176 177 <h3>Styling</h3> 178 179 <p> 180 The following optional parameters may be passed to affect the style of the embedded Tweet. 181 These are passed directly through to Twitter's Javascript. 182 </p> 183 184 <p> 185 <ul> 186 <li> 187 <tt style="color: green;">align</tt> 188 - Alignment of the embedded Tweet inside the iframe - can be 189 <tt style="color: green;">left</tt>, 190 <tt style="color: green;">center</tt>, or 191 <tt style="color: green;">right</tt> 192 </li> 193 194 <li> 195 <tt style="color: green;">link_color</tt> 196 - Hex code for link color 197 </li> 198 199 <li> 200 <tt style="color: green;">theme</tt> 201 - <a 202 rel="noopener noreferrer" 203 target="_blank" 204 href="https://dev.twitter.com/web/embedded-tweets/parameters" 205 >Theme</a> of Tweet display (such as <tt>dark</tt>) 206 </li> 207 208 <li> 209 <tt style="color: green;">conversation</tt> 210 - Disable showing previous Tweet in a thread when set to <tt>none</tt> 211 </li> 212 </ul> 213 </p> 214 215 <h3 id="sizing">Sizing</h3> 216 217 <p> 218 As with any iframe, its height and width within the parent document are static, and must be included as attributes in the 219 <tt>&lt;iframe&gt;</tt> tag or applied with CSS. Reasonable recommendations to display most Tweets (without embedded media) 220 without scrolling are <tt>height="300"</tt> and <tt>width="550"</tt>. 221 To automatically resize the height of the iframe after it has loaded, some Javascript is required. 222 </p> 223 224 <p> 225 Since a parent HTML page loading an iframe from <tt>tf.rita.moe</tt> has loaded a cross-origin resource, the parent HTML page is not 226 permitted to access the iframe's DOM to find out its height. Newer browsers implementing 227 <tt><a 228 rel="noopener noreferrer" 229 target="_blank" 230 href="https://developer.mozilla.org/en-US/docs/DOM/window.postMessage" 231 >window.postMessage</a></tt> 232 can send a message to the tf.rita.moe iframe (which it is listening for) and request its height after Twitter's Javascript loads. 233 <tt>tf.rita.moe</tt> will send a response message with the height after it has loaded the Twitter content. 234 </p> 235 236 <p> 237 Using Javascript, the following code will send a message to each <tt>&lt;iframe&gt;</tt> element on the page that you have named like 238 "<tt>tweet_281974362784022528</tt>": 239 </p> 240 241 <p> 242<pre> 243document.addEventListener('DOMContentLoaded', () => { 244 // Find all iframes with ids starting with "tweet_" 245 const tweetIframes = document.querySelectorAll('iframe[id^="tweet_"]') 246 tweetIframes.forEach((iframe) => { 247 iframe.addEventListener('load', () => { 248 iframe.contentWindow.postMessage( 249 { 250 element: iframe.id, 251 query: 'height' 252 }, 253 'https://tf.rita.moe', 254 ) 255 }) 256 }) 257}) 258 259// Listen for the return message once the tweet has been loaded 260window.addEventListener('message', (e) => { 261 if (e.origin !== 'https://tf.rita.moe') return 262 263 const data = e.data 264 if (data?.height && data?.element?.match(/^tweet_/)) { 265 const iframe = document.getElementById(data.element) 266 if (iframe) { 267 iframe.style.height = parseInt(data.height, 10) + 'px' 268 } 269 } 270}) 271</pre> 272 </p> 273 274 <p> 275 This code resizes the twitframe iframes after they have loaded, increasing the height to display the embedded card information. 276 </p> 277 278 <iframe 279 border="0" 280 frameborder="0" 281 height="300" 282 id="tweet_1291863596922806273" 283 src="https://tf.rita.moe/show?url=https%3A%2F%2Ftwitter.com%2Felonmusk%2Fstatus%2F1604617643973124097&amp;conversation=none" 284 width="550" 285 ></iframe> 286 287 <script> 288 document.addEventListener('DOMContentLoaded', () => { 289 // Find all iframes with ids starting with "tweet_" 290 const tweetIframes = document.querySelectorAll('iframe[id^="tweet_"]') 291 tweetIframes.forEach((iframe) => { 292 iframe.addEventListener('load', () => { 293 iframe.contentWindow.postMessage( 294 { 295 element: iframe.id, 296 query: 'height' 297 }, 298 'https://tf.rita.moe', 299 ) 300 }) 301 }) 302 }) 303 304 // Listen for the return message once the tweet has been loaded 305 window.addEventListener('message', (e) => { 306 if (e.origin !== 'https://tf.rita.moe') return 307 308 const data = e.data 309 if (data?.height && data?.element?.match(/^tweet_/)) { 310 const iframe = document.getElementById(data.element) 311 if (iframe) { 312 iframe.style.height = parseInt(data.height, 10) + 'px' 313 } 314 } 315 }) 316 </script> 317</body> 318</html>