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