chore: clean up and unified patterns 6f590883
Steve · 2026-04-01 20:03 49 file(s) · +84 −103
apps/feeds/assets/android-chrome-192x192.png → apps/feeds/static/android-chrome-192x192.png +0 −0

Binary file — no preview.

apps/feeds/assets/android-chrome-512x512.png → apps/feeds/static/android-chrome-512x512.png +0 −0

Binary file — no preview.

apps/feeds/assets/apple-touch-icon.png → apps/feeds/static/apple-touch-icon.png +0 −0

Binary file — no preview.

apps/feeds/assets/favicon-16x16.png → apps/feeds/static/favicon-16x16.png +0 −0

Binary file — no preview.

apps/feeds/assets/favicon-32x32.png → apps/feeds/static/favicon-32x32.png +0 −0

Binary file — no preview.

apps/feeds/assets/favicon.ico → apps/feeds/static/favicon.ico +0 −0

Binary file — no preview.

apps/feeds/assets/fonts/CommitMono-400-Italic.otf → apps/feeds/static/fonts/CommitMono-400-Italic.otf +0 −0

Binary file — no preview.

apps/feeds/assets/fonts/CommitMono-400-Regular.otf → apps/feeds/static/fonts/CommitMono-400-Regular.otf +0 −0

Binary file — no preview.

apps/feeds/assets/fonts/CommitMono-700-Italic.otf → apps/feeds/static/fonts/CommitMono-700-Italic.otf +0 −0

Binary file — no preview.

apps/feeds/assets/fonts/CommitMono-700-Regular.otf → apps/feeds/static/fonts/CommitMono-700-Regular.otf +0 −0

Binary file — no preview.

apps/feeds/assets/icon.png → apps/feeds/static/icon.png +0 −0

Binary file — no preview.

apps/feeds/assets/og.png → apps/feeds/static/og.png +0 −0

Binary file — no preview.

apps/feeds/assets/site.webmanifest → apps/feeds/static/site.webmanifest +0 −0
apps/feeds/assets/styles.css → apps/feeds/static/styles.css +0 −0
apps/feeds/src/main.rs +15 −5
17 17
use std::sync::Arc;
18 18
19 19
#[derive(Embed)]
20 -
#[folder = "assets/"]
21 -
struct Assets;
20 +
#[folder = "static/"]
21 +
struct Static;
22 22
23 23
pub struct AppState {
24 24
    sessions: auth::SessionStore,
25 25
    admin_password: Option<String>,
26 26
    cookie_secure: bool,
27 +
    base_url: String,
27 28
}
28 29
29 30
struct TemplateFeedItem {
36 37
#[derive(Template)]
37 38
#[template(path = "index.html")]
38 39
struct IndexTemplate {
40 +
    base_url: String,
39 41
    items: Vec<TemplateFeedItem>,
40 42
    feed_urls: Option<Vec<String>>,
41 43
    error: Option<String>,
69 71
    Some((url, username, password))
70 72
}
71 73
72 -
async fn index_handler(Query(params): Query<HashMap<String, String>>) -> impl IntoResponse {
74 +
async fn index_handler(
75 +
    State(state): State<Arc<AppState>>,
76 +
    Query(params): Query<HashMap<String, String>>,
77 +
) -> impl IntoResponse {
73 78
    let url_query = params
74 79
        .get("url")
75 80
        .or_else(|| params.get("urls"))
88 93
                .collect();
89 94
90 95
            IndexTemplate {
96 +
                base_url: state.base_url.clone(),
91 97
                items: template_items,
92 98
                feed_urls,
93 99
                error: None,
96 102
        Err(e) => {
97 103
            eprintln!("Error fetching feeds: {e}");
98 104
            IndexTemplate {
105 +
                base_url: state.base_url.clone(),
99 106
                items: Vec::new(),
100 107
                feed_urls: None,
101 108
                error: Some("Error loading feeds. Please try again later.".to_string()),
188 195
}
189 196
190 197
async fn static_handler(axum::extract::Path(path): axum::extract::Path<String>) -> Response {
191 -
    match Assets::get(&path) {
198 +
    match Static::get(&path) {
192 199
        Some(file) => {
193 200
            let mime = mime_guess::from_path(&path).first_or_octet_stream();
194 201
            (
327 334
        .map(|v| v.eq_ignore_ascii_case("true"))
328 335
        .unwrap_or(false);
329 336
337 +
    let base_url = std::env::var("BASE_URL").unwrap_or_else(|_| "http://localhost:4555".to_string());
338 +
330 339
    let state = Arc::new(AppState {
331 340
        sessions: auth::new_session_store(),
332 341
        admin_password: std::env::var("ADMIN_PASSWORD").ok(),
333 342
        cookie_secure,
343 +
        base_url,
334 344
    });
335 345
336 346
    let app = Router::new()
343 353
        )
344 354
        .route("/admin/logout", get(logout_handler))
345 355
        .route("/admin/add-feed", post(add_feed_handler))
346 -
        .route("/assets/{*path}", get(static_handler))
356 +
        .route("/static/{*path}", get(static_handler))
347 357
        .with_state(state);
348 358
349 359
    let listener = tokio::net::TcpListener::bind("0.0.0.0:4555")
apps/feeds/src/templates/admin.html +5 −5
4 4
    <meta charset="UTF-8" />
5 5
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 6
    <meta name="theme-color" content="#121113" />
7 -
    <link rel="stylesheet" href="/assets/styles.css" />
8 -
    <link rel="apple-touch-icon" sizes="180x180" href="https://feeds.stevedylan.dev/assets/apple-touch-icon.png">
9 -
    <link rel="icon" type="image/png" sizes="32x32" href="https://feeds.stevedylan.dev/assets/favicon-32x32.png">
10 -
    <link rel="icon" type="image/png" sizes="16x16" href="https://feeds.stevedylan.dev/assets/favicon-16x16.png">
11 -
    <link rel="manifest" href="https://feeds.stevedylan.dev/assets/site.webmanifest">
7 +
    <link rel="stylesheet" href="/static/styles.css" />
8 +
    <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
9 +
    <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
10 +
    <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
11 +
    <link rel="manifest" href="/static/site.webmanifest">
12 12
    <title>Feeds | Admin</title>
13 13
  </head>
14 14
  <body>
apps/feeds/src/templates/index.html +9 −10
4 4
    <meta charset="UTF-8" />
5 5
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 6
    <meta name="theme-color" content="#121113" />
7 -
    <link rel="stylesheet" href="/assets/styles.css" />
8 -
    <link rel="apple-touch-icon" sizes="180x180" href="https://feeds.stevedylan.dev/assets/apple-touch-icon.png">
9 -
    <link rel="icon" type="image/png" sizes="32x32" href="https://feeds.stevedylan.dev/assets/favicon-32x32.png">
10 -
    <link rel="icon" type="image/png" sizes="16x16" href="https://feeds.stevedylan.dev/assets/favicon-16x16.png">
11 -
    <link rel="manifest" href="https://feeds.stevedylan.dev/assets/site.webmanifest">
7 +
    <link rel="stylesheet" href="/static/styles.css" />
8 +
    <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
9 +
    <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
10 +
    <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
11 +
    <link rel="manifest" href="/static/site.webmanifest">
12 12
13 13
    <title>Feeds</title>
14 14
    <meta name="description" content="Minimal RSS Reading">
15 15
16 -
    <meta property="og:url" content="https://feeds.stevedylan.dev">
16 +
    <meta property="og:url" content="{{ base_url }}">
17 17
    <meta property="og:type" content="website">
18 18
    <meta property="og:title" content="Feeds">
19 19
    <meta property="og:description" content="Minimal RSS Reading">
20 -
    <meta property="og:image" content="https://feeds.stevedylan.dev/assets/og.png">
20 +
    <meta property="og:image" content="{{ base_url }}/static/og.png">
21 21
22 22
    <meta name="twitter:card" content="summary_large_image">
23 -
    <meta property="twitter:domain" content="feeds.stevedylan.dev">
24 -
    <meta property="twitter:url" content="https://feeds.stevedylan.dev">
23 +
    <meta property="twitter:url" content="{{ base_url }}">
25 24
    <meta name="twitter:title" content="Feeds">
26 25
    <meta name="twitter:description" content="Minimal RSS Reading">
27 -
    <meta name="twitter:image" content="https://feeds.stevedylan.dev/assets/og.png">
26 +
    <meta name="twitter:image" content="{{ base_url }}/static/og.png">
28 27
  </head>
29 28
  <body>
30 29
    <a href="/" class="header">
apps/feeds/src/templates/login.html +5 −5
4 4
    <meta charset="UTF-8" />
5 5
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 6
    <meta name="theme-color" content="#121113" />
7 -
    <link rel="stylesheet" href="/assets/styles.css" />
8 -
    <link rel="apple-touch-icon" sizes="180x180" href="https://feeds.stevedylan.dev/assets/apple-touch-icon.png">
9 -
    <link rel="icon" type="image/png" sizes="32x32" href="https://feeds.stevedylan.dev/assets/favicon-32x32.png">
10 -
    <link rel="icon" type="image/png" sizes="16x16" href="https://feeds.stevedylan.dev/assets/favicon-16x16.png">
11 -
    <link rel="manifest" href="https://feeds.stevedylan.dev/assets/site.webmanifest">
7 +
    <link rel="stylesheet" href="/static/styles.css" />
8 +
    <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
9 +
    <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
10 +
    <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
11 +
    <link rel="manifest" href="/static/site.webmanifest">
12 12
    <title>Feeds | Login</title>
13 13
  </head>
14 14
  <body>
apps/jotts/assets/fonts/CommitMono-400-Regular.otf → apps/jotts/static/fonts/CommitMono-400-Regular.otf +0 −0

Binary file — no preview.

apps/jotts/assets/fonts/CommitMono-700-Regular.otf → apps/jotts/static/fonts/CommitMono-700-Regular.otf +0 −0

Binary file — no preview.

apps/jotts/src/server.rs +0 −20
21 21
}
22 22
23 23
#[derive(Embed)]
24 -
#[folder = "assets/"]
25 -
struct Assets;
26 -
27 -
#[derive(Embed)]
28 24
#[folder = "static/"]
29 25
struct Static;
30 26
99 95
        "otf" => "font/otf",
100 96
        "json" | "webmanifest" => "application/json",
101 97
        _ => "application/octet-stream",
102 -
    }
103 -
}
104 -
105 -
async fn serve_asset(Path(path): Path<String>) -> Response {
106 -
    match Assets::get(&path) {
107 -
        Some(file) => {
108 -
            let mime = mime_from_path(&path);
109 -
            (
110 -
                StatusCode::OK,
111 -
                [(axum::http::header::CONTENT_TYPE, HeaderValue::from_static(mime))],
112 -
                file.data.to_vec(),
113 -
            )
114 -
                .into_response()
115 -
        }
116 -
        None => StatusCode::NOT_FOUND.into_response(),
117 98
    }
118 99
}
119 100
397 378
        .route("/notes/{short_id}", post(post_update_note))
398 379
        .route("/notes/{short_id}/delete", post(post_delete_note))
399 380
        // Static assets
400 -
        .route("/assets/{*path}", get(serve_asset))
401 381
        .route("/static/{*path}", get(serve_static))
402 382
        .with_state(state);
403 383
apps/jotts/static/styles.css +2 −2
1 1
@font-face {
2 2
  font-family: "Commit Mono";
3 -
  src: url("/assets/fonts/CommitMono-400-Regular.otf") format("opentype");
3 +
  src: url("/static/fonts/CommitMono-400-Regular.otf") format("opentype");
4 4
  font-weight: 400;
5 5
  font-style: normal;
6 6
}
7 7
8 8
@font-face {
9 9
  font-family: "Commit Mono";
10 -
  src: url("/assets/fonts/CommitMono-700-Regular.otf") format("opentype");
10 +
  src: url("/static/fonts/CommitMono-700-Regular.otf") format("opentype");
11 11
  font-weight: 700;
12 12
  font-style: normal;
13 13
}
apps/og/static/assets/fonts/.gitkeep (deleted) +0 −0

Binary file — no preview.

apps/og/static/assets/fonts/CommitMono-400-Regular.otf (deleted) +0 −0

Binary file — no preview.

apps/og/static/assets/fonts/CommitMono-700-Regular.otf (deleted) +0 −0

Binary file — no preview.

apps/og/static/styles.css +2 −2
1 1
@font-face {
2 2
    font-family: "Commit Mono";
3 -
    src: url("/static/assets/fonts/CommitMono-400-Regular.otf") format("opentype");
3 +
    src: url("/static/fonts/CommitMono-400-Regular.otf") format("opentype");
4 4
    font-weight: 400;
5 5
    font-style: normal;
6 6
}
7 7
8 8
@font-face {
9 9
    font-family: "Commit Mono";
10 -
    src: url("/static/assets/fonts/CommitMono-700-Regular.otf") format("opentype");
10 +
    src: url("/static/fonts/CommitMono-700-Regular.otf") format("opentype");
11 11
    font-weight: 700;
12 12
    font-style: normal;
13 13
}
apps/parcels/static/assets/fonts/.gitkeep (deleted) +0 −0

Binary file — no preview.

apps/parcels/static/assets/fonts/CommitMono-400-Regular.otf (deleted) +0 −0

Binary file — no preview.

apps/parcels/static/assets/fonts/CommitMono-700-Regular.otf (deleted) +0 −0

Binary file — no preview.

apps/parcels/templates/base.html +3 −3
3 3
<head>
4 4
  <meta charset="UTF-8">
5 5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 -
  <title>{% block title %}PARCELS{% endblock %}</title>
6 +
  <title>{% block title %}Parcels{% endblock %}</title>
7 7
  <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
8 8
  <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
9 9
  <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
15 15
  <style>
16 16
    @font-face {
17 17
      font-family: 'CommitMono';
18 -
      src: url('/static/assets/fonts/CommitMono-400-Regular.otf') format('opentype');
18 +
      src: url('/static/fonts/CommitMono-400-Regular.otf') format('opentype');
19 19
      font-weight: 400;
20 20
    }
21 21
    @font-face {
22 22
      font-family: 'CommitMono';
23 -
      src: url('/static/assets/fonts/CommitMono-700-Regular.otf') format('opentype');
23 +
      src: url('/static/fonts/CommitMono-700-Regular.otf') format('opentype');
24 24
      font-weight: 700;
25 25
    }
26 26
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
apps/shrink/templates/base.html +1 −1
4 4
    <meta charset="UTF-8">
5 5
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 6
    <meta name="theme-color" content="#121113">
7 -
    <title>{% block title %}SHRINK{% endblock %}</title>
7 +
    <title>{% block title %}Shrink{% endblock %}</title>
8 8
    <meta name="description" content="Shorten URLs with SHRINK">
9 9
    <meta property="og:title" content="SHRINK">
10 10
    <meta property="og:description" content="Shorten URLs with SHRINK">
apps/sipp/assets/android-chrome-192x192.png → apps/sipp/static/android-chrome-192x192.png +0 −0

Binary file — no preview.

apps/sipp/assets/android-chrome-512x512.png → apps/sipp/static/android-chrome-512x512.png +0 −0

Binary file — no preview.

apps/sipp/assets/apple-touch-icon.png → apps/sipp/static/apple-touch-icon.png +0 −0

Binary file — no preview.

apps/sipp/assets/favicon-16x16.png → apps/sipp/static/favicon-16x16.png +0 −0

Binary file — no preview.

apps/sipp/assets/favicon-32x32.png → apps/sipp/static/favicon-32x32.png +0 −0

Binary file — no preview.

apps/sipp/assets/favicon.ico → apps/sipp/static/favicon.ico +0 −0

Binary file — no preview.

apps/sipp/assets/fonts/CommitMono-400-Italic.otf → apps/sipp/static/fonts/CommitMono-400-Italic.otf +0 −0

Binary file — no preview.

apps/sipp/assets/fonts/CommitMono-400-Regular.otf → apps/sipp/static/fonts/CommitMono-400-Regular.otf +0 −0

Binary file — no preview.

apps/sipp/assets/fonts/CommitMono-700-Italic.otf → apps/sipp/static/fonts/CommitMono-700-Italic.otf +0 −0

Binary file — no preview.

apps/sipp/assets/fonts/CommitMono-700-Regular.otf → apps/sipp/static/fonts/CommitMono-700-Regular.otf +0 −0

Binary file — no preview.

apps/sipp/assets/icon.png → apps/sipp/static/icon.png +0 −0

Binary file — no preview.

apps/sipp/assets/og.png → apps/sipp/static/og.png +0 −0

Binary file — no preview.

apps/sipp/assets/site.webmanifest → apps/sipp/static/site.webmanifest +0 −0
apps/sipp/src/server.rs +16 −21
17 17
use std::sync::Arc;
18 18
19 19
#[derive(Embed)]
20 -
#[folder = "assets/"]
21 -
struct Assets;
22 -
23 -
#[derive(Embed)]
24 20
#[folder = "static/"]
25 21
struct Static;
26 22
56 52
    db: Db,
57 53
    highlighter: Arc<Highlighter>,
58 54
    server_config: ServerConfig,
55 +
    base_url: String,
59 56
}
60 57
61 58
#[derive(Template)]
62 59
#[template(path = "index.html")]
63 -
struct IndexTemplate;
60 +
struct IndexTemplate {
61 +
    base_url: String,
62 +
}
64 63
65 64
#[derive(Template)]
66 65
#[template(path = "admin.html")]
67 -
struct AdminTemplate;
66 +
struct AdminTemplate {
67 +
    base_url: String,
68 +
}
68 69
69 70
#[derive(Template)]
70 71
#[template(path = "snippet.html")]
71 72
struct SnippetTemplate {
73 +
    base_url: String,
72 74
    name: String,
73 75
    content: String,
74 76
    highlighted_content: String,
80 82
    content: String,
81 83
}
82 84
83 -
async fn index() -> WebTemplate<IndexTemplate> {
84 -
    WebTemplate(IndexTemplate)
85 +
async fn index(State(state): State<AppState>) -> WebTemplate<IndexTemplate> {
86 +
    WebTemplate(IndexTemplate { base_url: state.base_url.clone() })
85 87
}
86 88
87 -
async fn admin() -> WebTemplate<AdminTemplate> {
88 -
    WebTemplate(AdminTemplate)
89 +
async fn admin(State(state): State<AppState>) -> WebTemplate<AdminTemplate> {
90 +
    WebTemplate(AdminTemplate { base_url: state.base_url.clone() })
89 91
}
90 92
91 93
fn is_cli_user_agent(headers: &HeaderMap) -> bool {
116 118
                let highlighted_content =
117 119
                    state.highlighter.highlight(&snippet.name, &snippet.content);
118 120
                Ok(WebTemplate(SnippetTemplate {
121 +
                    base_url: state.base_url.clone(),
119 122
                    name: snippet.name,
120 123
                    content: snippet.content,
121 124
                    highlighted_content,
328 331
    }
329 332
}
330 333
331 -
async fn serve_assets(Path(path): Path<String>) -> Response {
332 -
    match Assets::get(&path) {
333 -
        Some(file) => {
334 -
            let mime = mime_from_path(&path);
335 -
            ([(header::CONTENT_TYPE, mime)], file.data).into_response()
336 -
        }
337 -
        None => StatusCode::NOT_FOUND.into_response(),
338 -
    }
339 -
}
340 -
341 334
async fn serve_static(Path(path): Path<String>) -> Response {
342 335
    match Static::get(&path) {
343 336
        Some(file) => {
374 367
375 368
    println!("Max content size: {} bytes", server_config.max_content_size);
376 369
370 +
    let base_url = std::env::var("BASE_URL").unwrap_or_else(|_| "http://localhost:3000".to_string());
371 +
377 372
    let state = AppState {
378 373
        db: db::init_db().expect("Failed to initialize database"),
379 374
        highlighter: Arc::new(Highlighter::new()),
380 375
        server_config,
376 +
        base_url,
381 377
    };
382 378
383 379
    let api_routes = build_api_routes(&state);
388 384
        .route("/s/{short_id}", get(view_snippet))
389 385
        .route("/snippets", post(create_snippet))
390 386
        .merge(api_routes)
391 -
        .route("/assets/{*path}", get(serve_assets))
392 387
        .route("/static/{*path}", get(serve_static))
393 388
        .with_state(state);
394 389
apps/sipp/static/styles.css +2 −2
154 154
155 155
@font-face {
156 156
	font-family: "Commit Mono";
157 -
	src: url("/assets/fonts/CommitMono-400-Regular.otf") format("opentype");
157 +
	src: url("/static/fonts/CommitMono-400-Regular.otf") format("opentype");
158 158
	font-weight: 400;
159 159
	font-style: normal;
160 160
}
161 161
162 162
@font-face {
163 163
	font-family: "Commit Mono";
164 -
	src: url("/assets/fonts/CommitMono-700-Regular.otf") format("opentype");
164 +
	src: url("/static/fonts/CommitMono-700-Regular.otf") format("opentype");
165 165
	font-weight: 700;
166 166
	font-style: normal;
167 167
}
apps/sipp/templates/admin.html +8 −9
5 5
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 6
    <meta name="theme-color" content="#121113" />
7 7
    <link rel="stylesheet" href="/static/styles.css" />
8 -
    <link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png">
9 -
    <link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png">
10 -
    <link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png">
11 -
    <link rel="manifest" href="/assets/site.webmanifest">
8 +
    <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
9 +
    <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
10 +
    <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
11 +
    <link rel="manifest" href="/static/site.webmanifest">
12 12
13 13
    <title>Sipp - Admin</title>
14 14
    <meta name="description" content="Minimal Code Sharing">
15 15
16 -
    <meta property="og:url" content="https://sipp.so">
16 +
    <meta property="og:url" content="{{ base_url }}">
17 17
    <meta property="og:type" content="website">
18 18
    <meta property="og:title" content="Sipps">
19 19
    <meta property="og:description" content="Minimal Code Sharing">
20 -
    <meta property="og:image" content="https://sipp.so/assets/og.png">
20 +
    <meta property="og:image" content="{{ base_url }}/static/og.png">
21 21
22 22
    <meta name="twitter:card" content="summary_large_image">
23 -
    <meta property="twitter:domain" content="sipp.so">
24 -
    <meta property="twitter:url" content="https://sipp.so">
23 +
    <meta property="twitter:url" content="{{ base_url }}">
25 24
    <meta name="twitter:title" content="Sipps">
26 25
    <meta name="twitter:description" content="Minimal Code Sharing">
27 -
    <meta name="twitter:image" content="https://sipp.so/assets/og.png">
26 +
    <meta name="twitter:image" content="{{ base_url }}/static/og.png">
28 27
  </head>
29 28
  <body>
30 29
apps/sipp/templates/index.html +8 −9
5 5
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 6
    <meta name="theme-color" content="#121113" />
7 7
    <link rel="stylesheet" href="/static/styles.css" />
8 -
    <link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png">
9 -
    <link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png">
10 -
    <link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png">
11 -
    <link rel="manifest" href="/assets/site.webmanifest">
8 +
    <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
9 +
    <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
10 +
    <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
11 +
    <link rel="manifest" href="/static/site.webmanifest">
12 12
13 13
    <title>Sipp</title>
14 14
    <meta name="description" content="Minimal Code Sharing">
15 15
16 -
    <meta property="og:url" content="https://sipp.so">
16 +
    <meta property="og:url" content="{{ base_url }}">
17 17
    <meta property="og:type" content="website">
18 18
    <meta property="og:title" content="Sipps">
19 19
    <meta property="og:description" content="Minimal Code Sharing">
20 -
    <meta property="og:image" content="https://sipp.so/assets/og.png">
20 +
    <meta property="og:image" content="{{ base_url }}/static/og.png">
21 21
22 22
    <meta name="twitter:card" content="summary_large_image">
23 -
    <meta property="twitter:domain" content="sipp.so">
24 -
    <meta property="twitter:url" content="https://sipp.so">
23 +
    <meta property="twitter:url" content="{{ base_url }}">
25 24
    <meta name="twitter:title" content="Sipps">
26 25
    <meta name="twitter:description" content="Minimal Code Sharing">
27 -
    <meta name="twitter:image" content="https://sipp.so/assets/og.png">
26 +
    <meta name="twitter:image" content="{{ base_url }}/static/og.png">
28 27
  </head>
29 28
  <body>
30 29
apps/sipp/templates/snippet.html +8 −9
5 5
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 6
    <link rel="stylesheet" href="/static/styles.css" />
7 7
    <meta name="theme-color" content="#121113" />
8 -
    <link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png">
9 -
    <link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png">
10 -
    <link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png">
11 -
    <link rel="manifest" href="/assets/site.webmanifest">
8 +
    <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
9 +
    <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
10 +
    <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
11 +
    <link rel="manifest" href="/static/site.webmanifest">
12 12
13 13
    <title>{{ name }} | Sipp</title>
14 14
    <meta name="description" content="Minimal Code Sharing">
15 15
16 -
    <meta property="og:url" content="https://sipp.so">
16 +
    <meta property="og:url" content="{{ base_url }}">
17 17
    <meta property="og:type" content="website">
18 18
    <meta property="og:title" content="Sipp | {{ name }}">
19 19
    <meta property="og:description" content="Minimal Code Sharing">
20 -
    <meta property="og:image" content="https://sipp.so/assets/og.png">
20 +
    <meta property="og:image" content="{{ base_url }}/static/og.png">
21 21
22 22
    <meta name="twitter:card" content="summary_large_image">
23 -
    <meta property="twitter:domain" content="sipp.so">
24 -
    <meta property="twitter:url" content="https://sipp.so">
23 +
    <meta property="twitter:url" content="{{ base_url }}">
25 24
    <meta name="twitter:title" content="Sipp | {{ name }}">
26 25
    <meta name="twitter:description" content="Minimal Code Sharing">
27 -
    <meta name="twitter:image" content="https://sipp.so/assets/og.png">
26 +
    <meta name="twitter:image" content="{{ base_url }}/static/og.png">
28 27
29 28
  </head>
30 29
  <body>