Files
direct-img.link/index.html
T
multipleof4andClaude Opus 5.5 3121dd0dda Feat: Newsletter sign-up at the bottom of the homepage
A "Get Updates" form subscribes emails to the direct-img pool on
newsletter.planetrenox.com, behind the shared "newsletter" Turnstile
widget (direct-img.link was added to its allowed domains). The privacy
policy now covers what sign-up stores and the Turnstile script.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 03:24:35 +00:00

193 lines
13 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>direct-img.link | Live images in markdown</title>
<meta name="description" content="Embed live images in markdown powered by search. No APIs, no tokens, just search.">
<link rel="icon" href="/assets/favicon.ico" sizes="16x16 32x32 48x48"><link rel="icon" href="/assets/logo.svg" type="image/svg+xml">
<script data-goatcounter="https://direct-img.goatcounter.com/count"
async src="//gc.zgo.at/count.js"></script>
<style>
:root{--bg:#fff;--text:#1a1a1a;--text-muted:#666;--accent:#0070f3;--warning:#eb5757;--code-bg:#f5f5f5;--border:#eaeaea;--radius:8px;}
*{box-sizing:border-box;}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;line-height:1.6;color:var(--text);background-color:var(--bg);margin:0;display:flex;flex-direction:column;align-items:center;}
main{max-width:680px;width:100%;padding:80px 24px;}
h1{font-size:2.5rem;font-weight:800;letter-spacing:-0.02em;margin-bottom:8px;}
p.tagline{font-size:1.25rem;color:var(--text-muted);margin-bottom:32px;}
.status-notice{padding:20px;background:#fff5f5;border:1px solid #ffe0e0;border-radius:var(--radius);margin-bottom:48px;}
.status-notice p{margin:0;font-size:1rem;}
.status-notice strong{color:var(--warning);}
.donate{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:12px;}
.btc-address{font-family:monospace;background:rgba(0,0,0,0.05);padding:4px 8px;border-radius:4px;font-size:0.85rem;word-break:break-all;display:inline-block;}
section{margin-bottom:48px;}
h2{font-size:1.5rem;font-weight:700;margin-bottom:16px;border-bottom:1px solid var(--border);padding-bottom:8px;}
pre{background:var(--code-bg);padding:16px;border-radius:var(--radius);overflow-x:auto;font-size:0.9rem;border:1px solid var(--border);}
.copy-wrap{position:relative;}
.copy-wrap pre{white-space:pre-wrap;padding-right:72px;}
.copy{position:absolute;top:8px;right:8px;font:inherit;font-size:0.75rem;font-weight:600;padding:4px 10px;border:1px solid var(--border);border-radius:6px;background:var(--bg);color:var(--text-muted);cursor:pointer;}
.copy:hover{color:var(--accent);border-color:var(--accent);}
code{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,monospace;}
table{width:100%;border-collapse:collapse;margin:16px 0;font-size:0.9rem;}
th,td{text-align:left;padding:12px;border-bottom:1px solid var(--border);}
th{color:var(--text-muted);font-weight:600;}
.card{border:1px solid var(--border);padding:16px;border-radius:var(--radius);}
.card h3{margin:0 0 8px 0;font-size:1rem;}
.card p{margin:0;font-size:0.9rem;color:var(--text-muted);}
.sub{display:flex;flex-wrap:wrap;gap:8px;}
.sub input{flex:1;min-width:200px;font:inherit;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);color:var(--text);}
.sub input:focus{outline:none;border-color:var(--accent);}
.sub button{font:inherit;font-weight:600;padding:10px 20px;border:0;border-radius:var(--radius);background:var(--accent);color:#fff;cursor:pointer;}
.sub button:disabled{opacity:.6;cursor:default;}
.cf-turnstile{margin-top:8px;}
#sub-msg{margin:8px 0 0;font-size:0.9rem;}
footer{width:100%;max-width:680px;padding:40px 24px;border-top:1px solid var(--border);color:var(--text-muted);font-size:0.9rem;display:flex;justify-content:space-between;margin-top:auto;}
a{color:var(--accent);text-decoration:none;} a:hover{text-decoration:underline;}
@media(max-width:600px){h1{font-size:2rem;}}
</style>
</head>
<body>
<main>
<h1>direct-img.link</h1>
<p class="tagline">Live images in markdown, powered by search.</p>
<section class="status-notice">
<p>This service is <strong>free</strong> to use. However, search API and server costs are high. Without community donations, <strong>this project will die quickly.</strong></p>
<p style="margin-top:10px;">If we receive significant donations, we will <strong>increase the daily search limits</strong> for everyone.</p>
<div class="donate">
<iframe src="https://github.com/sponsors/multipleof4/button" title="Sponsor multipleof4" height="32" width="114" style="border:0;border-radius:6px;"></iframe>
<div class="btc-address">BTC: bc1q3d975cd57205dx6mz05s2g27xujxsc3q0nlv59</div>
</div>
</section>
<section>
<h2>For AI System Prompts</h2>
<p>Add this to your system instructions:</p>
<div class="copy-wrap">
<button class="copy" onclick="copyPrompt(this)">Copy</button>
<pre><code id="prompt">When writing markdown, embed relevant images/gifs using direct-img.link — a free image search proxy that returns images directly from a URL. But keep it entertaining, for example use it to show reaction faces, girl, or fun, not technical.
Example structure:
![Cat Gif](https://direct-img.link/cat+gif)
Use images to complement your responses, powered by Brave.</code></pre>
</div>
</section>
<section>
<h2>Usage</h2>
<p>Embed directly in your markdown files:</p>
<pre><code>![orange cat](https://direct-img.link/orange+cat)</code></pre>
<p>Not the image you wanted? Add <code>?i=2</code> (up to <code>20</code>) to serve the next one:</p>
<pre><code>![orange cat](https://direct-img.link/orange+cat?i=2)</code></pre>
<p style="font-size:0.85rem;margin-top:12px;color:var(--text-muted);">* Note: Literal dots (.) and slashes (/) are rejected to prevent bot abuse. Use <code>%2E</code> or <code>%2F</code> if your query requires them.</p>
</section>
<section>
<h2>Free Images</h2>
<p>Need images you can publish? <code>free.direct-img.link</code> only serves images marked <strong>free of restrictions</strong> (public domain or CC0), so no credit is needed.</p>
<pre><code>![orange cat](https://free.direct-img.link/orange+cat)
![orange cat](https://free.direct-img.link/orange+cat?i=2)
![orange cat](https://free.direct-img.link/orange+cat?src=wikimedia&amp;i=2)</code></pre>
<table>
<thead>
<tr><th>Param</th><th>Values</th><th>Default</th></tr>
</thead>
<tbody>
<tr><td><code>src</code></td><td><code>openverse</code>, <code>wikimedia</code></td><td>Openverse, then Wikimedia</td></tr>
<tr><td><code>i</code></td><td><code>1</code>–<code>20</code> (which result)</td><td><code>1</code></td></tr>
</tbody>
</table>
<p style="font-size:0.85rem;color:var(--text-muted);">* Both params are optional and work in any order. Licenses come from each source and can be wrong, so check the original before publishing. Images from <a href="https://openverse.org">Openverse</a> (made using the Openverse API, not endorsed or certified by Openverse) and <a href="https://commons.wikimedia.org">Wikimedia Commons</a>.</p>
</section>
<section>
<h2>AI Images</h2>
<p><code>ai.direct-img.link</code> generates an image of anything instead of searching, so it never comes up empty. Expect soft, painterly, abstract results: the right colors and mood, not always the exact thing.</p>
<pre><code>![frog wizard](https://ai.direct-img.link/frog+wizard)
![frog wizard](https://ai.direct-img.link/frog+wizard?i=2)
![frog wizard](https://ai.direct-img.link/frog+wizard?src=auroraimg-6m&amp;i=2)</code></pre>
<table>
<thead>
<tr><th>Param</th><th>Values</th><th>Default</th></tr>
</thead>
<tbody>
<tr><td><code>src</code></td><td><code>auroraimg-6m</code></td><td><code>auroraimg-6m</code></td></tr>
<tr><td><code>i</code></td><td><code>1</code>–<code>20</code> (a different image each)</td><td><code>1</code></td></tr>
</tbody>
</table>
<p style="font-size:0.85rem;color:var(--text-muted);">* The same query always gives the same image. When a search on direct-img.link or free.direct-img.link finds nothing, an AI image is served instead. Made with <a href="https://github.com/direct-img/AuroraIMG-6M">AuroraIMG-6M</a>.</p>
</section>
<section>
<h2>Rate Limits</h2>
<table>
<thead>
<tr><th>Scope</th><th>Limit</th><th>Action</th></tr>
</thead>
<tbody>
<tr><td>Burst</td><td>~10 req/10s per IP</td><td>HTTP 429 (~10s)</td></tr>
<tr><td>New Searches</td><td><span data-limit="DAILY_LIMIT">35</span> per day per IP</td><td>Limit image served</td></tr>
<tr><td>New Free Searches</td><td><span data-limit="FREE_DAILY_LIMIT">100</span> per day per IP</td><td>Limit image served</td></tr>
<tr><td>New AI Images</td><td><span data-limit="AI_DAILY_LIMIT">100</span> per day per IP</td><td>Limit image served</td></tr>
</tbody>
</table>
<p style="font-size:0.85rem;color:var(--text-muted);">* free.direct-img.link and ai.direct-img.link each have their own daily limit, separate from the main site's. Cached images don't count toward it and keep loading after you hit it. The burst limit applies to all image requests and is enforced approximately. The daily limit resets at 00:00 UTC.</p>
</section>
<section>
<div class="card">
<h3>Caching</h3>
<p>Images are cached for 90 days. Subsequent requests for the same query are served instantly. Searches that find nothing serve an AI image instead, cached the same way.</p>
</div>
</section>
<section>
<h2>Get Updates</h2>
<p>Get an email when direct-img.link gets new features, sources, or higher limits. No spam.</p>
<form onsubmit="event.preventDefault();sub(this)">
<div class="sub">
<input type="email" name="email" required placeholder="you@example.com" autocomplete="email" aria-label="Email address">
<button type="submit">Sign up</button>
</div>
<div class="cf-turnstile" data-sitekey="0x4AAAAAAFG4HWETOcDDQ5vg" data-appearance="interaction-only" data-size="flexible"></div>
<p id="sub-msg" role="status"></p>
</form>
<p style="font-size:0.85rem;color:var(--text-muted);">* Unsubscribe anytime with the link in any email. We never share your email.</p>
</section>
</main>
<footer>
<div>Built for the AI era.</div>
<div><a href="https://github.com/direct-img/direct-img.link/blob/main/TERMS.md">Terms</a> · <a href="https://github.com/direct-img/direct-img.link/blob/main/PRIVACY.md">Privacy</a> · <a href="https://github.com/direct-img/direct-img.link">GitHub</a></div>
</footer>
<script>
const copyPrompt=b=>{
const p=document.getElementById('prompt');
(navigator.clipboard?.writeText(p.textContent)??Promise.reject()).then(()=>{
b.textContent='Copied!';
setTimeout(()=>b.textContent='Copy',1500);
},()=>getSelection().selectAllChildren(p));
};
const sub=async f=>{
const b=f.querySelector('button'),m=document.getElementById('sub-msg'),tok=()=>f.querySelector('[name=cf-turnstile-response]')?.value;
b.disabled=true;b.textContent='Signing up…';m.textContent='';
for(let i=0;i<50&&!tok();i++)await new Promise(r=>setTimeout(r,100));
let ok=false,e='Network error. Please try again.';
try{
const r=await fetch('https://newsletter.planetrenox.com/api/sub',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({pool:'direct-img',email:f.email.value.trim(),token:tok()||''})}),d=await r.json();
ok=r.ok&&d.ok;
e={'invalid email':"That email doesn't look right.",'captcha failed':"Couldn't verify you're human. Please try again."}[d.error]??'Something went wrong. Please try again.';
}catch{}
m.textContent=ok?"You're signed up. Thanks!":e;
m.style.color=ok?'#1a7f37':'var(--warning)';
if(ok)f.reset();
window.turnstile?.reset();
b.disabled=false;b.textContent='Sign up';
};
</script>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<script type="module">
import * as L from '/assets/rate-limit.js';
for(const e of document.querySelectorAll('[data-limit]'))e.textContent=L[e.dataset.limit]??e.textContent;
</script>
</body>
</html>