bingo: serve real favicon files
The favicon was an emoji in a data: URI and /favicon.ico was a 404. Google only shows a site icon in results when the favicon has a crawlable URL, and the emoji looked different on every platform. Add an SVG (a 5x5 card with a crossed-out diagonal), a 16/32/48 ICO and a 180px apple-touch-icon under assets/bingo/, served by explicit routes because public/ belongs to asxp.io. Assisted-by: Claude:opus-5
This commit is contained in:
parent
d2d6ac1d99
commit
cb2eba1a26
6 changed files with 25 additions and 1 deletions
BIN
assets/bingo/apple-touch-icon.png
Normal file
BIN
assets/bingo/apple-touch-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
BIN
assets/bingo/favicon.ico
Normal file
BIN
assets/bingo/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
1
assets/bingo/favicon.svg
Normal file
1
assets/bingo/favicon.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="12" fill="#121212"/><rect x="5" y="5" width="10" height="10" rx="1.5" fill="#ff6a4d"/><rect x="16" y="5" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="27" y="5" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="38" y="5" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="49" y="5" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="5" y="16" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="16" y="16" width="10" height="10" rx="1.5" fill="#ff6a4d"/><rect x="27" y="16" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="38" y="16" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="49" y="16" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="5" y="27" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="16" y="27" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="27" y="27" width="10" height="10" rx="1.5" fill="#ff6a4d"/><rect x="38" y="27" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="49" y="27" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="5" y="38" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="16" y="38" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="27" y="38" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="38" y="38" width="10" height="10" rx="1.5" fill="#ff6a4d"/><rect x="49" y="38" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="5" y="49" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="16" y="49" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="27" y="49" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="38" y="49" width="10" height="10" rx="1.5" fill="#ece7dc"/><rect x="49" y="49" width="10" height="10" rx="1.5" fill="#ff6a4d"/></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
10
bingo_web.rb
10
bingo_web.rb
|
|
@ -111,6 +111,16 @@ class BingoWeb < Sinatra::Base
|
|||
erb :index
|
||||
end
|
||||
|
||||
# Icons from assets/bingo/ (public/ is asxp.io's). Search engines want
|
||||
# a crawlable favicon URL; a data: URI doesn't count.
|
||||
ICONS = { 'favicon.svg' => 'image/svg+xml', 'favicon.ico' => 'image/x-icon',
|
||||
'apple-touch-icon.png' => 'image/png' }.freeze
|
||||
|
||||
get %r{/(favicon\.svg|favicon\.ico|apple-touch-icon\.png)} do |name|
|
||||
cache_control :public, max_age: 86_400
|
||||
send_file File.join(settings.root, 'assets', 'bingo', name), type: ICONS[name]
|
||||
end
|
||||
|
||||
# Photos are immutable per key (a new upload gets a new key).
|
||||
get '/p/:file' do
|
||||
bytes, type = Bingo::Photo.read(params[:file])
|
||||
|
|
|
|||
|
|
@ -190,6 +190,17 @@ class BingoTest < Minitest::Test
|
|||
assert_equal 'http://example.org/en?view=operational', last_response.location
|
||||
end
|
||||
|
||||
def test_icons
|
||||
{ '/favicon.svg' => 'image/svg+xml', '/favicon.ico' => 'image/x-icon',
|
||||
'/apple-touch-icon.png' => 'image/png' }.each do |path, type|
|
||||
get path
|
||||
assert last_response.ok?, path
|
||||
assert_equal type, last_response.content_type
|
||||
end
|
||||
get '/en'
|
||||
assert_includes last_response.body, '<link rel="icon" href="/favicon.svg" type="image/svg+xml">'
|
||||
end
|
||||
|
||||
def test_root_varies_on_language
|
||||
get '/'
|
||||
assert_equal 'Accept-Language', last_response.headers['Vary']
|
||||
|
|
|
|||
|
|
@ -34,7 +34,9 @@
|
|||
<meta name="twitter:title" content="<%= t(:seo_title) %>">
|
||||
<meta name="twitter:description" content="<%= desc %>">
|
||||
<script type="application/ld+json"><%== json_ld(@board, desc) %></script>
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🎱</text></svg>">
|
||||
<link rel="icon" href="/favicon.ico" sizes="48x48">
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||
<style>
|
||||
:root {
|
||||
--bg: #f4f1ea; --card: #fffdf8; --ink: #1d1b18; --muted: #6f6a60; --line: #d9d3c6;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue