
Adding audio to your blog
Audio posts usually need browser controls or a more customized interface. This post starts with platform controls, then styles those controls, and finally replaces them with a Howler-enhanced interface. Each pattern uses a local audio file.
The baseline native <audio> element
Browsers provide controls and accessibility behavior. If their styling is acceptable, this is the smallest solution.
<audio controls>
<source src="audio.mp3" type="audio/mpeg">
</audio>The trade-off is presentation. Browsers style their controls differently, and the page has limited control over the interface.
A styled native player
The native element needs no custom JavaScript. A surrounding panel can add a title and credits without replacing the browser controls. The site stylesheet defines .audio-native; the markup remains ordinary HTML:
<section class="audio-native">
<h3>Audio in your blog</h3>
<p>Female Speaker | Blog of Thomas Weitzel | 2026</p>
<audio controls src="audio.mp3">
Your browser does not support the audio element.
</audio>
</section>Audio in your blog
Female Speaker | Blog of Thomas Weitzel | 2026
Custom player
Use a custom player when the interface needs a consistent visual design. Heine passes trusted Markdown HTML through unchanged, so the post can declare the player directly. The nested <audio> element remains the fallback. Page-local scripts upgrade it after they load and restore the native controls if Howler cannot initialize.
<site-audio-player duration="00:47">
<h3>Audio in your blog</h3>
<p>Female Speaker | Blog of Thomas Weitzel | 2026</p>
<audio controls src="audio.mp3">
Your browser does not support the audio element.
</audio>
</site-audio-player>
<script src="howler.js"></script>
<script src="audio-player.js"></script>
<script src="audio-init.js"></script>Audio in your blog
Female Speaker | Blog of Thomas Weitzel | 2026
The custom player gives the post a consistent interface. Native audio remains useful when platform controls and a smaller dependency surface matter more.
Notes
- Keep media and player scripts beside the post that uses them when no other page needs them.
heine servesupports byte-range requests, so local audio playback and seeking work in the development server.