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 213 <li> 214 <tt style="color: green;">cards</tt> 215 - Disable showing media previews when set to <tt>hidden</tt> 216 </li> 217 218 <li> 219 <tt style="color: green;">lang</tt> 220 - Language code for the interface (such as <tt>en</tt>) 221 </li> 222 </ul> 223 </p> 224 225 <h3 id="sizing">Sizing</h3> 226 227 <p> 228 As with any iframe, its height and width within the parent document are static, and must be included as attributes in the 229 <tt>&lt;iframe&gt;</tt> tag or applied with CSS. Reasonable recommendations to display most Tweets (without embedded media) 230 without scrolling are <tt>height="300"</tt> and <tt>width="550"</tt>. 231 To automatically resize the height of the iframe after it has loaded, some Javascript is required. 232 </p> 233 234 <p> 235 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 236 permitted to access the iframe's DOM to find out its height. Newer browsers implementing 237 <tt><a 238 rel="noopener noreferrer" 239 target="_blank" 240 href="https://developer.mozilla.org/en-US/docs/DOM/window.postMessage" 241 >window.postMessage</a></tt> 242 can send a message to the tf.rita.moe iframe (which it is listening for) and request its height after Twitter's Javascript loads. 243 <tt>tf.rita.moe</tt> will send a response message with the height after it has loaded the Twitter content. 244 </p> 245 246 <p> 247 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 248 "<tt>tweet_281974362784022528</tt>": 249 </p> 250 251 <p> 252<pre> 253document.addEventListener('DOMContentLoaded', () => { 254 // Find all iframes with ids starting with "tweet_" 255 const tweetIframes = document.querySelectorAll('iframe[id^="tweet_"]') 256 tweetIframes.forEach((iframe) => { 257 iframe.addEventListener('load', () => { 258 iframe.contentWindow.postMessage( 259 { 260 element: iframe.id, 261 query: 'height' 262 }, 263 'https://tf.rita.moe', 264 ) 265 }) 266 }) 267}) 268 269// Listen for the return message once the tweet has been loaded 270window.addEventListener('message', (e) => { 271 if (e.origin !== 'https://tf.rita.moe') return 272 273 const data = e.data 274 if (data?.height && data?.element?.match(/^tweet_/)) { 275 const iframe = document.getElementById(data.element) 276 if (iframe) { 277 iframe.style.height = parseInt(data.height, 10) + 'px' 278 } 279 } 280}) 281</pre> 282 </p> 283 284 <p> 285 This code resizes the twitframe iframes after they have loaded, increasing the height to display the embedded card information. 286 </p> 287 288 <iframe 289 border="0" 290 frameborder="0" 291 height="300" 292 id="tweet_1291863596922806273" 293 src="https://tf.rita.moe/show?url=https%3A%2F%2Ftwitter.com%2Felonmusk%2Fstatus%2F1604617643973124097&amp;conversation=none" 294 width="550" 295 ></iframe> 296 297 <script> 298 document.addEventListener('DOMContentLoaded', () => { 299 // Find all iframes with ids starting with "tweet_" 300 const tweetIframes = document.querySelectorAll('iframe[id^="tweet_"]') 301 tweetIframes.forEach((iframe) => { 302 iframe.addEventListener('load', () => { 303 iframe.contentWindow.postMessage( 304 { 305 element: iframe.id, 306 query: 'height' 307 }, 308 'https://tf.rita.moe', 309 ) 310 }) 311 }) 312 }) 313 314 // Listen for the return message once the tweet has been loaded 315 window.addEventListener('message', (e) => { 316 if (e.origin !== 'https://tf.rita.moe') return 317 318 const data = e.data 319 if (data?.height && data?.element?.match(/^tweet_/)) { 320 const iframe = document.getElementById(data.element) 321 if (iframe) { 322 iframe.style.height = parseInt(data.height, 10) + 'px' 323 } 324 } 325 }) 326 </script> 327</body> 328</html>