Changeset 6be57b4 in Klonkt


Ignore:
Timestamp:
06/19/2026 04:13:46 AM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
b9dc94c
Parents:
1794fac
Message:

Embeddable player (premium feature #7)

Standalone /embed page (no shell) with a compact audio player for the site
tracks, intended for an <iframe> on external sites. The page runs on the klonkt
origin, so audio requests from the iframe remain same-origin -> the
/audio/stream gate lets them through, even on an external site. Helmet's
X-Frame-Options + frame-ancestors are overridden per route (frame-ancestors *)
so external embedding is allowed.

  • routes/embed.js (premium-gated): GET /embed.
  • views/pages/embed-player.ejs: standalone HTML, inline css/js, play/pause, track click, auto-next, progress bar; themable on site.accent.
  • admin-audio: embedUrl + "Embeddable player" section with copyable iframe code + preview link (premium).

node --check passed.

Co-Authored-By: Claude <noreply@…>

Location:
src
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • src/routes/admin-audio.js

    r1794fac r6be57b4  
    9191  }));
    9292
     93  const base = (process.env.PUBLIC_BASE_URL || ('https://' + (req.get('host') || ''))).replace(/\/$/, '');
     94  const embedUrl = base + (res.locals.siteUrlBase || '') + '/embed';
    9395  renderPage(req, res, 'pages/admin-audio', {
    9496    pageTitle: 'Audio tracks',
    9597    bodyClass: 'on-admin',
    9698    tracks,
     99    embedUrl,
    97100    error: req.query.error || null,
    98101    success: req.query.success || null,
  • src/server.js

    r1794fac r6be57b4  
    5757import downloadRoutes from './routes/download.js';
    5858import linkbioRoutes from './routes/linkbio.js';
     59import embedRoutes from './routes/embed.js';
    5960
    6061if (!process.env.SESSION_SECRET) {
     
    275276app.use('/', downloadRoutes); // /downloads + /download/:id download-voor-email (premium)
    276277app.use('/', linkbioRoutes); // /links link-in-bio + klikstats (premium)
     278app.use('/', embedRoutes); // /embed inbedbare audiospeler (premium)
    277279app.use('/', postsRoutes);
    278280
  • src/views/pages/admin-audio.ejs

    r1794fac r6be57b4  
    115115    <% } %>
    116116  </section>
     117
     118  <% if ((typeof premiumUnlocked === 'undefined' || premiumUnlocked) && typeof embedUrl !== 'undefined') { %>
     119    <section class="ax-section" style="margin-top:1.5rem">
     120      <h2 style="margin:0 0 .4rem">🔊 Embedbare speler</h2>
     121      <p style="opacity:.75;font-size:.9rem;margin:0 0 .6rem">Plak deze code op je eigen website/blog om je muziek met deze speler in te sluiten:</p>
     122      <textarea readonly rows="3" onclick="this.select()" style="width:100%;font-family:monospace;font-size:12px;padding:10px;border-radius:8px;border:1px solid var(--rule);background:var(--paper-2);color:inherit;">&lt;iframe src="<%= embedUrl %>" width="100%" height="420" frameborder="0" loading="lazy" style="border-radius:12px"&gt;&lt;/iframe&gt;</textarea>
     123      <p style="margin:.6rem 0 0"><a class="btn" href="<%= embedUrl %>" target="_blank">▶ Speler-voorbeeld openen</a></p>
     124    </section>
     125  <% } %>
    117126
    118127</div>
Note: See TracChangeset for help on using the changeset viewer.