Essentials for learning: italki, Anki, Ordnet.dk.

Here is a userscript which displays a ‘Download’ button next to the audio button on https://ordnet.dk/. Useful for quickly downloading the audio of the pronunciation for that word e.g. for importing Anki.

// ==UserScript==
// @name         Ordnet DDO Audio Download Button
// @namespace    https://ordnet.dk/
// @version      1.1
// @description  Adds download buttons next to pronunciation audio on ordnet.dk/ddo/ordbog result pages
// @author       Callum Tennant
// @match        https://ordnet.dk/ddo/ordbog*
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    function addDownloadButtons() {
        const udtaleBox = document.querySelector('#id-udt');
        if (!udtaleBox) return;

        const wordElem = document.querySelector('.match');
        const baseWord = wordElem ? wordElem.textContent.trim().toLowerCase() : 'unknown';

        const lydskriftSpans = udtaleBox.querySelectorAll('.lydskrift');

        lydskriftSpans.forEach(span => {
            const fallbackLink = span.querySelector('a[id$="_fallback"]');
            const speakerImg = span.querySelector('img[onclick^="playSound"]');

            if (fallbackLink && speakerImg && !span.querySelector('.download-button')) {
                const mp3Url = fallbackLink.href;
                const filename = `danish-${baseWord}.mp3`;

                const btn = document.createElement('button');
                btn.textContent = 'Download';
                btn.className = 'download-button';
                btn.style.marginLeft = '8px';
                btn.style.fontSize = '0.9em';
                btn.style.cursor = 'pointer';
                btn.style.backgroundColor = '#0074d9';
                btn.style.color = '#fff';
                btn.style.border = 'none';
                btn.style.borderRadius = '4px';
                btn.style.padding = '2px 6px';

                btn.addEventListener('click', () => {
                    GM_xmlhttpRequest({
                        method: 'GET',
                        url: mp3Url,
                        responseType: 'blob',
                        onload: function (response) {
                            const blob = response.response;
                            const url = URL.createObjectURL(blob);
                            const a = document.createElement('a');
                            a.href = url;
                            a.download = filename;
                            document.body.appendChild(a);
                            a.click();
                            document.body.removeChild(a);
                            URL.revokeObjectURL(url);
                        },
                        onerror: function (error) {
                            alert('Download failed. See console.');
                            console.error('MP3 download error:', error);
                        }
                    });
                });

                speakerImg.parentNode.insertBefore(btn, speakerImg.nextSibling);
            }
        });
    }

    window.addEventListener('load', addDownloadButtons);

    const observer = new MutationObserver(() => {
        addDownloadButtons();
    });
    observer.observe(document.body, { childList: true, subtree: true });
})();