« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/data/things.js6
-rw-r--r--src/listing-spec.js100
-rw-r--r--src/misc-templates.js84
-rw-r--r--src/page/album-commentary.js24
-rw-r--r--src/page/album.js64
-rw-r--r--src/page/artist.js90
-rw-r--r--src/page/flash.js28
-rw-r--r--src/page/group.js40
-rw-r--r--src/page/homepage.js10
-rw-r--r--src/page/listing.js18
-rw-r--r--src/page/news.js16
-rw-r--r--src/page/tag.js10
-rw-r--r--src/page/track.js58
-rwxr-xr-xsrc/upd8.js26
-rw-r--r--src/util/strings.js12
15 files changed, 293 insertions, 293 deletions
diff --git a/src/data/things.js b/src/data/things.js
index a37ede7b..34946c0f 100644
--- a/src/data/things.js
+++ b/src/data/things.js
@@ -1494,7 +1494,7 @@ Object.assign(Language.prototype, {
 
     formatDuration(secTotal, {approximate = false, unit = false}) {
         if (secTotal === 0) {
-            return strings('count.duration.missing');
+            return language.$('count.duration.missing');
         }
 
         const hour = Math.floor(secTotal / 3600);
@@ -1537,8 +1537,8 @@ Object.assign(Language.prototype, {
             : value);
 
         const words = (value > 1000
-            ? strings('count.words.thousand', {words: num})
-            : strings('count.words', {words: num}));
+            ? language.$('count.words.thousand', {words: num})
+            : language.$('count.words', {words: num}));
 
         return this.$('count.words.withUnit.' + this.getUnitForm(value), {words});
     },
diff --git a/src/listing-spec.js b/src/listing-spec.js
index 3ee977d2..755564b9 100644
--- a/src/listing-spec.js
+++ b/src/listing-spec.js
@@ -19,7 +19,7 @@ const listingSpec = [
         },
 
         row(album, {link, strings}) {
-            return strings('listingPage.listAlbums.byName.item', {
+            return language.$('listingPage.listAlbums.byName.item', {
                 album: link.album(album),
                 tracks: language.countTracks(album.tracks.length, {unit: true})
             });
@@ -36,7 +36,7 @@ const listingSpec = [
         },
 
         row(album, {link, strings}) {
-            return strings('listingPage.listAlbums.byTracks.item', {
+            return language.$('listingPage.listAlbums.byTracks.item', {
                 album: link.album(album),
                 tracks: language.countTracks(album.tracks.length, {unit: true})
             });
@@ -54,7 +54,7 @@ const listingSpec = [
         },
 
         row({album, duration}, {link, strings}) {
-            return strings('listingPage.listAlbums.byDuration.item', {
+            return language.$('listingPage.listAlbums.byDuration.item', {
                 album: link.album(album),
                 duration: strings.count.duration(duration)
             });
@@ -70,7 +70,7 @@ const listingSpec = [
         },
 
         row(album, {link, strings}) {
-            return strings('listingPage.listAlbums.byDate.item', {
+            return language.$('listingPage.listAlbums.byDate.item', {
                 album: link.album(album),
                 date: strings.count.date(album.date)
             });
@@ -92,12 +92,12 @@ const listingSpec = [
             return fixWS`
                 <dl>
                     ${chunks.map(({dateAddedToWiki, chunk: albums}) => fixWS`
-                        <dt>${strings('listingPage.listAlbums.byDateAdded.date', {
+                        <dt>${language.$('listingPage.listAlbums.byDateAdded.date', {
                             date: strings.count.date(dateAddedToWiki)
                         })}</dt>
                         <dd><ul>
                             ${(albums
-                                .map(album => strings('listingPage.listAlbums.byDateAdded.album', {
+                                .map(album => language.$('listingPage.listAlbums.byDateAdded.album', {
                                     album: link.album(album)
                                 }))
                                 .map(row => `<li>${row}</li>`)
@@ -120,7 +120,7 @@ const listingSpec = [
         },
 
         row({artist, contributions}, {link, strings}) {
-            return strings('listingPage.listArtists.byName.item', {
+            return language.$('listingPage.listArtists.byName.item', {
                 artist: link.artist(artist),
                 contributions: language.countContributions(contributions, {unit: true})
             });
@@ -171,10 +171,10 @@ const listingSpec = [
             return fixWS`
                 <div class="content-columns">
                     <div class="column">
-                        <h2>${strings('listingPage.misc.trackContributors')}</h2>
+                        <h2>${language.$('listingPage.misc.trackContributors')}</h2>
                         <ul>
                             ${(toTracks
-                                .map(({ artist, contributions }) => strings('listingPage.listArtists.byContribs.item', {
+                                .map(({ artist, contributions }) => language.$('listingPage.listArtists.byContribs.item', {
                                     artist: link.artist(artist),
                                     contributions: language.countContributions(contributions, {unit: true})
                                 }))
@@ -183,13 +183,13 @@ const listingSpec = [
                          </ul>
                     </div>
                     <div class="column">
-                        <h2>${strings('listingPage.misc' +
+                        <h2>${language.$('listingPage.misc' +
                             (showAsFlashes
                                 ? '.artAndFlashContributors'
                                 : '.artContributors'))}</h2>
                         <ul>
                             ${(toArtAndFlashes
-                                .map(({ artist, contributions }) => strings('listingPage.listArtists.byContribs.item', {
+                                .map(({ artist, contributions }) => language.$('listingPage.listArtists.byContribs.item', {
                                     artist: link.artist(artist),
                                     contributions: language.countContributions(contributions, {unit: true})
                                 }))
@@ -217,7 +217,7 @@ const listingSpec = [
         },
 
         row({artist, entries}, {link, strings}) {
-            return strings('listingPage.listArtists.byCommentary.item', {
+            return language.$('listingPage.listArtists.byCommentary.item', {
                 artist: link.artist(artist),
                 entries: language.countCommentaryEntries(entries, {unit: true})
             });
@@ -242,7 +242,7 @@ const listingSpec = [
         },
 
         row({artist, duration}, {link, strings}) {
-            return strings('listingPage.listArtists.byDuration.item', {
+            return language.$('listingPage.listArtists.byDuration.item', {
                 artist: link.artist(artist),
                 duration: strings.count.duration(duration)
             });
@@ -297,10 +297,10 @@ const listingSpec = [
             return fixWS`
                 <div class="content-columns">
                     <div class="column">
-                        <h2>${strings('listingPage.misc.trackContributors')}</h2>
+                        <h2>${language.$('listingPage.misc.trackContributors')}</h2>
                         <ul>
                             ${(toTracks
-                                .map(({ artist, date }) => strings('listingPage.listArtists.byLatest.item', {
+                                .map(({ artist, date }) => language.$('listingPage.listArtists.byLatest.item', {
                                     artist: link.artist(artist),
                                     date: strings.count.date(date)
                                 }))
@@ -309,13 +309,13 @@ const listingSpec = [
                         </ul>
                     </div>
                     <div class="column">
-                        <h2>${strings('listingPage.misc' +
+                        <h2>${language.$('listingPage.misc' +
                             (showAsFlashes
                                 ? '.artAndFlashContributors'
                                 : '.artContributors'))}</h2>
                         <ul>
                             ${(toArtAndFlashes
-                                .map(({ artist, date }) => strings('listingPage.listArtists.byLatest.item', {
+                                .map(({ artist, date }) => language.$('listingPage.listArtists.byLatest.item', {
                                     artist: link.artist(artist),
                                     date: strings.count.date(date)
                                 }))
@@ -335,10 +335,10 @@ const listingSpec = [
         data: ({wikiData}) => wikiData.groupData.slice().sort(sortByName),
 
         row(group, {link, strings}) {
-            return strings('listingPage.listGroups.byCategory.group', {
+            return language.$('listingPage.listGroups.byCategory.group', {
                 group: link.groupInfo(group),
                 gallery: link.groupGallery(group, {
-                    text: strings('listingPage.listGroups.byCategory.group.gallery')
+                    text: language.$('listingPage.listGroups.byCategory.group.gallery')
                 })
             });
         }
@@ -354,15 +354,15 @@ const listingSpec = [
             return fixWS`
                 <dl>
                     ${groupCategoryData.map(category => fixWS`
-                        <dt>${strings('listingPage.listGroups.byCategory.category', {
+                        <dt>${language.$('listingPage.listGroups.byCategory.category', {
                             category: link.groupInfo(category.groups[0], {text: category.name})
                         })}</dt>
                         <dd><ul>
                             ${(category.groups
-                                .map(group => strings('listingPage.listGroups.byCategory.group', {
+                                .map(group => language.$('listingPage.listGroups.byCategory.group', {
                                     group: link.groupInfo(group),
                                     gallery: link.groupGallery(group, {
-                                        text: strings('listingPage.listGroups.byCategory.group.gallery')
+                                        text: language.$('listingPage.listGroups.byCategory.group.gallery')
                                     })
                                 }))
                                 .map(row => `<li>${row}</li>`)
@@ -386,7 +386,7 @@ const listingSpec = [
         },
 
         row({group, albums}, {link, strings}) {
-            return strings('listingPage.listGroups.byAlbums.item', {
+            return language.$('listingPage.listGroups.byAlbums.item', {
                 group: link.groupInfo(group),
                 albums: language.countAlbums(albums, {unit: true})
             });
@@ -405,7 +405,7 @@ const listingSpec = [
         },
 
         row({group, tracks}, {link, strings}) {
-            return strings('listingPage.listGroups.byTracks.item', {
+            return language.$('listingPage.listGroups.byTracks.item', {
                 group: link.groupInfo(group),
                 tracks: language.countTracks(tracks, {unit: true})
             });
@@ -424,7 +424,7 @@ const listingSpec = [
         },
 
         row({group, duration}, {link, strings}) {
-            return strings('listingPage.listGroups.byDuration.item', {
+            return language.$('listingPage.listGroups.byDuration.item', {
                 group: link.groupInfo(group),
                 duration: strings.count.duration(duration)
             });
@@ -462,7 +462,7 @@ const listingSpec = [
         },
 
         row({group, date}, {link, strings}) {
-            return strings('listingPage.listGroups.byLatest.item', {
+            return language.$('listingPage.listGroups.byLatest.item', {
                 group: link.groupInfo(group),
                 date: strings.count.date(date)
             });
@@ -478,7 +478,7 @@ const listingSpec = [
         },
 
         row(track, {link, strings}) {
-            return strings('listingPage.listTracks.byName.item', {
+            return language.$('listingPage.listTracks.byName.item', {
                 track: link.track(track)
             });
         }
@@ -493,12 +493,12 @@ const listingSpec = [
             return fixWS`
                 <dl>
                     ${albumData.map(album => fixWS`
-                        <dt>${strings('listingPage.listTracks.byAlbum.album', {
+                        <dt>${language.$('listingPage.listTracks.byAlbum.album', {
                             album: link.album(album)
                         })}</dt>
                         <dd><ol>
                             ${(album.tracks
-                                .map(track => strings('listingPage.listTracks.byAlbum.track', {
+                                .map(track => language.$('listingPage.listTracks.byAlbum.track', {
                                     track: link.track(track)
                                 }))
                                 .map(row => `<li>${row}</li>`)
@@ -525,17 +525,17 @@ const listingSpec = [
             return fixWS`
                 <dl>
                     ${chunks.map(({album, date, chunk: tracks}) => fixWS`
-                        <dt>${strings('listingPage.listTracks.byDate.album', {
+                        <dt>${language.$('listingPage.listTracks.byDate.album', {
                             album: link.album(album),
                             date: strings.count.date(date)
                         })}</dt>
                         <dd><ul>
                             ${(tracks
                                 .map(track => track.aka
-                                    ? `<li class="rerelease">${strings('listingPage.listTracks.byDate.track.rerelease', {
+                                    ? `<li class="rerelease">${language.$('listingPage.listTracks.byDate.track.rerelease', {
                                         track: link.track(track)
                                     })}</li>`
-                                    : `<li>${strings('listingPage.listTracks.byDate.track', {
+                                    : `<li>${language.$('listingPage.listTracks.byDate.track', {
                                         track: link.track(track)
                                     })}</li>`)
                                 .join('\n'))}
@@ -558,7 +558,7 @@ const listingSpec = [
         },
 
         row({track, duration}, {link, strings}) {
-            return strings('listingPage.listTracks.byDuration.item', {
+            return language.$('listingPage.listTracks.byDuration.item', {
                 track: link.track(track),
                 duration: strings.count.duration(duration)
             });
@@ -580,12 +580,12 @@ const listingSpec = [
             return fixWS`
                 <dl>
                     ${albums.map(({album, tracks}) => fixWS`
-                        <dt>${strings('listingPage.listTracks.byDurationInAlbum.album', {
+                        <dt>${language.$('listingPage.listTracks.byDurationInAlbum.album', {
                             album: link.album(album)
                         })}</dt>
                         <dd><ul>
                             ${(tracks
-                                .map(track => strings('listingPage.listTracks.byDurationInAlbum.track', {
+                                .map(track => language.$('listingPage.listTracks.byDurationInAlbum.track', {
                                     track: link.track(track),
                                     duration: strings.count.duration(track.duration)
                                 }))
@@ -610,7 +610,7 @@ const listingSpec = [
         },
 
         row({track, timesReferenced}, {link, strings}) {
-            return strings('listingPage.listTracks.byTimesReferenced.item', {
+            return language.$('listingPage.listTracks.byTimesReferenced.item', {
                 track: link.track(track),
                 timesReferenced: language.countTimesReferenced(timesReferenced, {unit: true})
             });
@@ -631,13 +631,13 @@ const listingSpec = [
             return fixWS`
                 <dl>
                     ${chunks.map(({album, chunk: tracks}) => fixWS`
-                        <dt>${strings('listingPage.listTracks.inFlashes.byAlbum.album', {
+                        <dt>${language.$('listingPage.listTracks.inFlashes.byAlbum.album', {
                             album: link.album(album),
                             date: strings.count.date(album.date)
                         })}</dt>
                         <dd><ul>
                             ${(tracks
-                                .map(track => strings('listingPage.listTracks.inFlashes.byAlbum.track', {
+                                .map(track => language.$('listingPage.listTracks.inFlashes.byAlbum.track', {
                                     track: link.track(track),
                                     flashes: strings.list.and(track.featuredInFlashes.map(link.flash))
                                 }))
@@ -660,13 +660,13 @@ const listingSpec = [
             return fixWS`
                 <dl>
                     ${sortByDate(flashData.slice()).map(flash => fixWS`
-                        <dt>${strings('listingPage.listTracks.inFlashes.byFlash.flash', {
+                        <dt>${language.$('listingPage.listTracks.inFlashes.byFlash.flash', {
                             flash: link.flash(flash),
                             date: strings.count.date(flash.date)
                         })}</dt>
                         <dd><ul>
                             ${(flash.featuredTracks
-                                .map(track => strings('listingPage.listTracks.inFlashes.byFlash.track', {
+                                .map(track => language.$('listingPage.listTracks.inFlashes.byFlash.track', {
                                     track: link.track(track),
                                     album: link.album(track.album)
                                 }))
@@ -691,13 +691,13 @@ const listingSpec = [
             return fixWS`
                 <dl>
                     ${chunks.map(({album, chunk: tracks}) => fixWS`
-                        <dt>${strings('listingPage.listTracks.withLyrics.album', {
+                        <dt>${language.$('listingPage.listTracks.withLyrics.album', {
                             album: link.album(album),
                             date: strings.count.date(album.date)
                         })}</dt>
                         <dd><ul>
                             ${(tracks
-                                .map(track => strings('listingPage.listTracks.withLyrics.track', {
+                                .map(track => language.$('listingPage.listTracks.withLyrics.track', {
                                     track: link.track(track),
                                 }))
                                 .map(row => `<li>${row}</li>`)
@@ -722,7 +722,7 @@ const listingSpec = [
         },
 
         row({tag, timesUsed}, {link, strings}) {
-            return strings('listingPage.listTags.byName.item', {
+            return language.$('listingPage.listTags.byName.item', {
                 tag: link.tag(tag),
                 timesUsed: language.countTimesUsed(timesUsed, {unit: true})
             });
@@ -742,7 +742,7 @@ const listingSpec = [
         },
 
         row({tag, timesUsed}, {link, strings}) {
-            return strings('listingPage.listTags.byUses.item', {
+            return language.$('listingPage.listTags.byUses.item', {
                 tag: link.tag(tag),
                 timesUsed: language.countTimesUsed(timesUsed, {unit: true})
             });
@@ -794,27 +794,27 @@ const filterListings = directoryPrefix => listingSpec
 
 const listingTargetSpec = [
     {
-        title: ({strings}) => strings('listingPage.target.album'),
+        title: ({strings}) => language.$('listingPage.target.album'),
         listings: filterListings('album')
     },
     {
-        title: ({strings}) => strings('listingPage.target.artist'),
+        title: ({strings}) => language.$('listingPage.target.artist'),
         listings: filterListings('artist')
     },
     {
-        title: ({strings}) => strings('listingPage.target.group'),
+        title: ({strings}) => language.$('listingPage.target.group'),
         listings: filterListings('group')
     },
     {
-        title: ({strings}) => strings('listingPage.target.track'),
+        title: ({strings}) => language.$('listingPage.target.track'),
         listings: filterListings('track')
     },
     {
-        title: ({strings}) => strings('listingPage.target.tag'),
+        title: ({strings}) => language.$('listingPage.target.tag'),
         listings: filterListings('tag')
     },
     {
-        title: ({strings}) => strings('listingPage.target.other'),
+        title: ({strings}) => language.$('listingPage.target.other'),
         listings: [
             listingSpec.find(l => l.directory === 'random')
         ]
diff --git a/src/misc-templates.js b/src/misc-templates.js
index 9a00d3b5..4d9939a1 100644
--- a/src/misc-templates.js
+++ b/src/misc-templates.js
@@ -67,7 +67,7 @@ export function generateChronologyLinks(currentThing, {
     }
 
     if (contributions.length > 8) {
-        return `<div class="chronology">${strings('misc.chronology.seeArtistPages')}</div>`;
+        return `<div class="chronology">${language.$('misc.chronology.seeArtistPages')}</div>`;
     }
 
     return contributions.map(({ who: artist }) => {
@@ -83,11 +83,11 @@ export function generateChronologyLinks(currentThing, {
         const parts = [
             previous && linkAnythingMan(previous, {
                 color: false,
-                text: strings('misc.nav.previous')
+                text: language.$('misc.nav.previous')
             }),
             next && linkAnythingMan(next, {
                 color: false,
-                text: strings('misc.nav.next')
+                text: language.$('misc.nav.next')
             })
         ].filter(Boolean);
 
@@ -102,7 +102,7 @@ export function generateChronologyLinks(currentThing, {
 
         return fixWS`
             <div class="chronology">
-                <span class="heading">${strings(headingString, stringOpts)}</span>
+                <span class="heading">${language.$(headingString, stringOpts)}</span>
                 ${parts.length && `<span class="buttons">(${parts.join(', ')})</span>`}
             </div>
         `;
@@ -112,7 +112,7 @@ export function generateChronologyLinks(currentThing, {
 // Content warning tags
 
 export function getRevealStringFromWarnings(warnings, {strings}) {
-    return strings('misc.contentWarnings', {warnings}) + `<br><span class="reveal-interaction">${strings('misc.contentWarnings.reveal')}</span>`
+    return language.$('misc.contentWarnings', {warnings}) + `<br><span class="reveal-interaction">${language.$('misc.contentWarnings.reveal')}</span>`
 }
 
 export function getRevealStringFromTags(tags, {strings}) {
@@ -152,7 +152,7 @@ export function generateCoverLink({
             })}
             ${wikiInfo.enableArtTagUI && tags.filter(tag => !tag.isContentWarning).length && fixWS`
                 <p class="tags">
-                    ${strings('releaseInfo.artTags')}
+                    ${language.$('releaseInfo.artTags')}
                     ${(tags
                         .filter(tag => !tag.isContentWarning)
                         .map(link.tag)
@@ -214,23 +214,23 @@ export function fancifyURL(url, {strings, album = false} = {}) {
         domain = local;
     }
     return fixWS`<a href="${url}" class="nowrap">${
-        domain === local ? strings('misc.external.local') :
-        domain.includes('bandcamp.com') ? strings('misc.external.bandcamp') :
-        BANDCAMP_DOMAINS.includes(domain) ? strings('misc.external.bandcamp.domain', {domain}) :
-        MASTODON_DOMAINS.includes(domain) ? strings('misc.external.mastodon.domain', {domain}) :
+        domain === local ? language.$('misc.external.local') :
+        domain.includes('bandcamp.com') ? language.$('misc.external.bandcamp') :
+        BANDCAMP_DOMAINS.includes(domain) ? language.$('misc.external.bandcamp.domain', {domain}) :
+        MASTODON_DOMAINS.includes(domain) ? language.$('misc.external.mastodon.domain', {domain}) :
         domain.includes('youtu') ? (album
             ? (url.includes('list=')
-                ? strings('misc.external.youtube.playlist')
-                : strings('misc.external.youtube.fullAlbum'))
-            : strings('misc.external.youtube')) :
-        domain.includes('soundcloud') ? strings('misc.external.soundcloud') :
-        domain.includes('tumblr.com') ? strings('misc.external.tumblr') :
-        domain.includes('twitter.com') ? strings('misc.external.twitter') :
-        domain.includes('deviantart.com') ? strings('misc.external.deviantart') :
-        domain.includes('wikipedia.org') ? strings('misc.external.wikipedia') :
-        domain.includes('poetryfoundation.org') ? strings('misc.external.poetryFoundation') :
-        domain.includes('instagram.com') ? strings('misc.external.instagram') :
-        domain.includes('patreon.com') ? strings('misc.external.patreon') :
+                ? language.$('misc.external.youtube.playlist')
+                : language.$('misc.external.youtube.fullAlbum'))
+            : language.$('misc.external.youtube')) :
+        domain.includes('soundcloud') ? language.$('misc.external.soundcloud') :
+        domain.includes('tumblr.com') ? language.$('misc.external.tumblr') :
+        domain.includes('twitter.com') ? language.$('misc.external.twitter') :
+        domain.includes('deviantart.com') ? language.$('misc.external.deviantart') :
+        domain.includes('wikipedia.org') ? language.$('misc.external.wikipedia') :
+        domain.includes('poetryfoundation.org') ? language.$('misc.external.poetryFoundation') :
+        domain.includes('instagram.com') ? language.$('misc.external.instagram') :
+        domain.includes('patreon.com') ? language.$('misc.external.patreon') :
         domain
     }</a>`;
 }
@@ -239,10 +239,10 @@ export function fancifyFlashURL(url, flash, {strings}) {
     const link = fancifyURL(url, {strings});
     return `<span class="nowrap">${
         url.includes('homestuck.com') ? (isNaN(Number(flash.page))
-            ? strings('misc.external.flash.homestuck.secret', {link})
-            : strings('misc.external.flash.homestuck.page', {link, page: flash.page})) :
-        url.includes('bgreco.net') ? strings('misc.external.flash.bgreco', {link}) :
-        url.includes('youtu') ? strings('misc.external.flash.youtube', {link}) :
+            ? language.$('misc.external.flash.homestuck.secret', {link})
+            : language.$('misc.external.flash.homestuck.page', {link, page: flash.page})) :
+        url.includes('bgreco.net') ? language.$('misc.external.flash.bgreco', {link}) :
+        url.includes('youtu') ? language.$('misc.external.flash.youtube', {link}) :
         link
     }</span>`;
 }
@@ -250,16 +250,16 @@ export function fancifyFlashURL(url, flash, {strings}) {
 export function iconifyURL(url, {strings, to}) {
     const domain = new URL(url).hostname;
     const [ id, msg ] = (
-        domain.includes('bandcamp.com') ? ['bandcamp', strings('misc.external.bandcamp')] :
-        BANDCAMP_DOMAINS.includes(domain) ? ['bandcamp', strings('misc.external.bandcamp.domain', {domain})] :
-        MASTODON_DOMAINS.includes(domain) ? ['mastodon', strings('misc.external.mastodon.domain', {domain})] :
-        domain.includes('youtu') ? ['youtube', strings('misc.external.youtube')] :
-        domain.includes('soundcloud') ? ['soundcloud', strings('misc.external.soundcloud')] :
-        domain.includes('tumblr.com') ? ['tumblr', strings('misc.external.tumblr')] :
-        domain.includes('twitter.com') ? ['twitter', strings('misc.external.twitter')] :
-        domain.includes('deviantart.com') ? ['deviantart', strings('misc.external.deviantart')] :
-        domain.includes('instagram.com') ? ['instagram', strings('misc.external.bandcamp')] :
-        ['globe', strings('misc.external.domain', {domain})]
+        domain.includes('bandcamp.com') ? ['bandcamp', language.$('misc.external.bandcamp')] :
+        BANDCAMP_DOMAINS.includes(domain) ? ['bandcamp', language.$('misc.external.bandcamp.domain', {domain})] :
+        MASTODON_DOMAINS.includes(domain) ? ['mastodon', language.$('misc.external.mastodon.domain', {domain})] :
+        domain.includes('youtu') ? ['youtube', language.$('misc.external.youtube')] :
+        domain.includes('soundcloud') ? ['soundcloud', language.$('misc.external.soundcloud')] :
+        domain.includes('tumblr.com') ? ['tumblr', language.$('misc.external.tumblr')] :
+        domain.includes('twitter.com') ? ['twitter', language.$('misc.external.twitter')] :
+        domain.includes('deviantart.com') ? ['deviantart', language.$('misc.external.deviantart')] :
+        domain.includes('instagram.com') ? ['instagram', language.$('misc.external.bandcamp')] :
+        ['globe', language.$('misc.external.domain', {domain})]
     );
     return fixWS`<a href="${url}" class="icon"><svg><title>${msg}</title><use href="${to('shared.staticFile', `icons.svg#icon-${id}`)}"></use></svg></a>`;
 }
@@ -305,11 +305,11 @@ export function getAlbumGridHTML({
     return getGridHTML({
         srcFn: getAlbumCover,
         linkFn: link.album,
-        detailsFn: details && (album => strings('misc.albumGrid.details', {
+        detailsFn: details && (album => language.$('misc.albumGrid.details', {
             tracks: language.countTracks(album.tracks.length, {unit: true}),
             time: strings.count.duration(getTotalDuration(album.tracks))
         })),
-        noSrcTextFn: album => strings('misc.albumGrid.noCoverArt', {
+        noSrcTextFn: album => language.$('misc.albumGrid.noCoverArt', {
             album: album.name
         }),
         ...props
@@ -337,11 +337,11 @@ export function generateInfoGalleryLinks(currentThing, isGallery, {
     return [
         link[linkKeyInfo](currentThing, {
             class: isGallery ? '' : 'current',
-            text: strings('misc.nav.info')
+            text: language.$('misc.nav.info')
         }),
         link[linkKeyGallery](currentThing, {
             class: isGallery ? 'current' : '',
-            text: strings('misc.nav.gallery')
+            text: language.$('misc.nav.gallery')
         })
     ].join(', ');
 }
@@ -364,7 +364,7 @@ export function generatePreviousNextLinks(current, {
                 id: 'previous-button',
                 title: previous.name
             },
-            text: strings('misc.nav.previous'),
+            text: language.$('misc.nav.previous'),
             color: false
         }),
         next && linkFn(next, {
@@ -372,7 +372,7 @@ export function generatePreviousNextLinks(current, {
                 id: 'next-button',
                 title: next.name
             },
-            text: strings('misc.nav.next'),
+            text: language.$('misc.nav.next'),
             color: false
         })
     ].filter(Boolean).join(', ');
@@ -405,5 +405,5 @@ export function getFooterLocalizationLinks(pathname, {
 
     return html.tag('div',
         {class: 'footer-localization-links'},
-        strings('misc.uiLanguage', {languages: links.join('\n')}));
+        language.$('misc.uiLanguage', {languages: links.join('\n')}));
 }
diff --git a/src/page/album-commentary.js b/src/page/album-commentary.js
index 90b36fc2..3c2b23cc 100644
--- a/src/page/album-commentary.js
+++ b/src/page/album-commentary.js
@@ -36,28 +36,28 @@ export function write(album, {wikiData}) {
             to,
             transformMultiline
         }) => ({
-            title: strings('albumCommentaryPage.title', {album: album.name}),
+            title: language.$('albumCommentaryPage.title', {album: album.name}),
             stylesheet: getAlbumStylesheet(album),
             theme: getThemeString(album.color),
 
             main: {
                 content: fixWS`
                     <div class="long-content">
-                        <h1>${strings('albumCommentaryPage.title', {
+                        <h1>${language.$('albumCommentaryPage.title', {
                             album: link.album(album)
                         })}</h1>
-                        <p>${strings('albumCommentaryPage.infoLine', {
+                        <p>${language.$('albumCommentaryPage.infoLine', {
                             words: `<b>${strings.count.words(words, {unit: true})}</b>`,
                             entries: `<b>${language.countCommentaryEntries(entries.length, {unit: true})}</b>`
                         })}</p>
                         ${album.commentary && fixWS`
-                            <h3>${strings('albumCommentaryPage.entry.title.albumCommentary')}</h3>
+                            <h3>${language.$('albumCommentaryPage.entry.title.albumCommentary')}</h3>
                             <blockquote>
                                 ${transformMultiline(album.commentary)}
                             </blockquote>
                         `}
                         ${album.tracks.filter(t => t.commentary).map(track => fixWS`
-                            <h3 id="${track.directory}">${strings('albumCommentaryPage.entry.title.trackCommentary', {
+                            <h3 id="${track.directory}">${language.$('albumCommentaryPage.entry.title.trackCommentary', {
                                 track: link.track(track)
                             })}</h3>
                             <blockquote style="${getLinkThemeString(track.color)}">
@@ -73,10 +73,10 @@ export function write(album, {wikiData}) {
                     {toHome: true},
                     {
                         path: ['localized.commentaryIndex'],
-                        title: strings('commentaryIndex.title')
+                        title: language.$('commentaryIndex.title')
                     },
                     {
-                        html: strings('albumCommentaryPage.nav.album', {
+                        html: language.$('albumCommentaryPage.nav.album', {
                             album: link.albumCommentary(album, {class: 'current'})
                         })
                     }
@@ -109,21 +109,21 @@ export function writeTargetless({wikiData}) {
             link,
             strings
         }) => ({
-            title: strings('commentaryIndex.title'),
+            title: language.$('commentaryIndex.title'),
 
             main: {
                 content: fixWS`
                     <div class="long-content">
-                        <h1>${strings('commentaryIndex.title')}</h1>
-                        <p>${strings('commentaryIndex.infoLine', {
+                        <h1>${language.$('commentaryIndex.title')}</h1>
+                        <p>${language.$('commentaryIndex.infoLine', {
                             words: `<b>${strings.count.words(totalWords, {unit: true})}</b>`,
                             entries: `<b>${language.countCommentaryEntries(totalEntries, {unit: true})}</b>`
                         })}</p>
-                        <p>${strings('commentaryIndex.albumList.title')}</p>
+                        <p>${language.$('commentaryIndex.albumList.title')}</p>
                         <ul>
                             ${data
                                 .map(({ album, entries, words }) => fixWS`
-                                    <li>${strings('commentaryIndex.albumList.item', {
+                                    <li>${language.$('commentaryIndex.albumList.item', {
                                         album: link.albumCommentary(album),
                                         words: strings.count.words(words, {unit: true}),
                                         entries: language.countCommentaryEntries(entries.length, {unit: true})
diff --git a/src/page/album.js b/src/page/album.js
index 66d4bfae..4b4ac6bd 100644
--- a/src/page/album.js
+++ b/src/page/album.js
@@ -41,11 +41,11 @@ export function write(album, {wikiData}) {
                 track.artistContribs.map(c => c.who),
                 album.artistContribs.map(c => c.who),
                 {checkOrder: false})
-                ? strings('trackList.item.withDuration', itemOpts)
-                : strings('trackList.item.withDuration.withArtists', {
+                ? language.$('trackList.item.withDuration', itemOpts)
+                : language.$('trackList.item.withDuration.withArtists', {
                     ...itemOpts,
                     by: `<span class="by">${
-                        strings('trackList.item.withArtists.by', {
+                        language.$('trackList.item.withArtists.by', {
                             artists: getArtistString(track.artistContribs)
                         })
                     }</span>`
@@ -121,7 +121,7 @@ export function write(album, {wikiData}) {
             const cover = getAlbumCover(album);
 
             return {
-                title: strings('albumPage.title', {album: album.name}),
+                title: language.$('albumPage.title', {album: album.name}),
                 stylesheet: getAlbumStylesheet(album),
                 theme: getThemeString(album.color, [
                     `--album-directory: ${album.directory}`
@@ -130,7 +130,7 @@ export function write(album, {wikiData}) {
                 banner: album.bannerArtistContribs.length && {
                     dimensions: album.bannerDimensions,
                     path: ['media.albumBanner', album.directory, album.bannerFileExtension],
-                    alt: strings('misc.alt.albumBanner'),
+                    alt: language.$('misc.alt.albumBanner'),
                     position: 'top'
                 },
 
@@ -138,58 +138,58 @@ export function write(album, {wikiData}) {
                     content: fixWS`
                         ${cover && generateCoverLink({
                             src: cover,
-                            alt: strings('misc.alt.albumCover'),
+                            alt: language.$('misc.alt.albumCover'),
                             tags: album.artTags
                         })}
-                        <h1>${strings('albumPage.title', {album: album.name})}</h1>
+                        <h1>${language.$('albumPage.title', {album: album.name})}</h1>
                         <p>
                             ${[
-                                album.artistContribs.length && strings('releaseInfo.by', {
+                                album.artistContribs.length && language.$('releaseInfo.by', {
                                     artists: getArtistString(album.artistContribs, {
                                         showContrib: true,
                                         showIcons: true
                                     })
                                 }),
-                                album.coverArtistContribs.length && strings('releaseInfo.coverArtBy', {
+                                album.coverArtistContribs.length && language.$('releaseInfo.coverArtBy', {
                                     artists: getArtistString(album.coverArtistContribs, {
                                         showContrib: true,
                                         showIcons: true
                                     })
                                 }),
-                                album.wallpaperArtistContribs.length && strings('releaseInfo.wallpaperArtBy', {
+                                album.wallpaperArtistContribs.length && language.$('releaseInfo.wallpaperArtBy', {
                                     artists: getArtistString(album.wallpaperArtistContribs, {
                                         showContrib: true,
                                         showIcons: true
                                     })
                                 }),
-                                album.bannerArtistContribs.length && strings('releaseInfo.bannerArtBy', {
+                                album.bannerArtistContribs.length && language.$('releaseInfo.bannerArtBy', {
                                     artists: getArtistString(album.bannerArtistContribs, {
                                         showContrib: true,
                                         showIcons: true
                                     })
                                 }),
-                                album.date && strings('releaseInfo.released', {
+                                album.date && language.$('releaseInfo.released', {
                                     date: strings.count.date(album.date)
                                 }),
                                 (album.coverArtDate &&
                                     +album.coverArtDate !== +album.date &&
-                                    strings('releaseInfo.artReleased', {
+                                    language.$('releaseInfo.artReleased', {
                                         date: strings.count.date(album.coverArtDate)
                                     })),
-                                strings('releaseInfo.duration', {
+                                language.$('releaseInfo.duration', {
                                     duration: strings.count.duration(albumDuration, {approximate: album.tracks.length > 1})
                                 })
                             ].filter(Boolean).join('<br>\n')}
                         </p>
                         ${commentaryEntries && `<p>${
-                            strings('releaseInfo.viewCommentary', {
+                            language.$('releaseInfo.viewCommentary', {
                                 link: link.albumCommentary(album, {
-                                    text: strings('releaseInfo.viewCommentary.link')
+                                    text: language.$('releaseInfo.viewCommentary.link')
                                 })
                             })
                         }</p>`}
                         ${album.urls?.length && `<p>${
-                            strings('releaseInfo.listenOn', {
+                            language.$('releaseInfo.listenOn', {
                                 links: strings.list.or(album.urls.map(url => fancifyURL(url, {album: true})))
                             })
                         }</p>`}
@@ -197,7 +197,7 @@ export function write(album, {wikiData}) {
                             <dl class="album-group-list">
                                 ${album.trackGroups.map(({ name, color, startIndex, tracks }) => fixWS`
                                     <dt>${
-                                        strings('trackList.group', {
+                                        language.$('trackList.group', {
                                             duration: strings.count.duration(getTotalDuration(tracks), {approximate: tracks.length > 1}),
                                             group: name
                                         })
@@ -215,14 +215,14 @@ export function write(album, {wikiData}) {
                         ${album.dateAddedToWiki && fixWS`
                             <p>
                                 ${[
-                                    strings('releaseInfo.addedToWiki', {
+                                    language.$('releaseInfo.addedToWiki', {
                                         date: strings.count.date(album.dateAddedToWiki)
                                     })
                                 ].filter(Boolean).join('<br>\n')}
                             </p>
                         `}
                         ${album.commentary && fixWS`
-                            <p>${strings('releaseInfo.artistCommentary')}</p>
+                            <p>${language.$('releaseInfo.artistCommentary')}</p>
                             <blockquote>
                                 ${transformMultiline(album.commentary)}
                             </blockquote>
@@ -243,7 +243,7 @@ export function write(album, {wikiData}) {
                     links: [
                         {toHome: true},
                         {
-                            html: strings('albumPage.nav.album', {
+                            html: language.$('albumPage.nav.album', {
                                 album: link.album(album, {class: 'current'})
                             })
                         },
@@ -276,7 +276,7 @@ export function generateAlbumSidebar(album, currentTrack, {
 
     /*
     const trackGroups = album.trackGroups || [{
-        name: strings('albumSidebar.trackList.fallbackGroupName'),
+        name: language.$('albumSidebar.trackList.fallbackGroupName'),
         color: album.color,
         startIndex: 0,
         tracks: album.tracks
@@ -287,13 +287,13 @@ export function generateAlbumSidebar(album, currentTrack, {
 
     const trackToListItem = track => html.tag('li',
         {class: track === currentTrack && 'current'},
-        strings('albumSidebar.trackList.item', {
+        language.$('albumSidebar.trackList.item', {
             track: link.track(track)
         }));
 
     const nameOrDefault = (isDefaultTrackGroup, name) =>
         (isDefaultTrackGroup
-            ? strings('albumSidebar.trackList.fallbackGroupName')
+            ? language.$('albumSidebar.trackList.fallbackGroupName')
             : name);
 
     const trackListPart = fixWS`
@@ -309,11 +309,11 @@ export function generateAlbumSidebar(album, currentTrack, {
                 html.tag('summary',
                     {style: getLinkThemeString(color)},
                     (listTag === 'ol'
-                        ? strings('albumSidebar.trackList.group.withRange', {
+                        ? language.$('albumSidebar.trackList.group.withRange', {
                             group: `<span class="group-name">${nameOrDefault(isDefaultTrackGroup, name)}</span>`,
                             range: `${startIndex + 1}&ndash;${startIndex + tracks.length}`
                         })
-                        : strings('albumSidebar.trackList.group', {
+                        : language.$('albumSidebar.trackList.group', {
                             group: `<span class="group-name">${nameOrDefault(isDefaultTrackGroup, name)}</span>`
                         }))
                 ),
@@ -335,24 +335,24 @@ export function generateAlbumSidebar(album, currentTrack, {
         return {group, next, previous};
     }).map(({group, next, previous}) => fixWS`
         <h1>${
-            strings('albumSidebar.groupBox.title', {
+            language.$('albumSidebar.groupBox.title', {
                 group: link.groupInfo(group)
             })
         }</h1>
         ${!currentTrack && transformMultiline(group.descriptionShort)}
         ${group.urls?.length && `<p>${
-            strings('releaseInfo.visitOn', {
+            language.$('releaseInfo.visitOn', {
                 links: strings.list.or(group.urls.map(url => fancifyURL(url)))
             })
         }</p>`}
         ${!currentTrack && fixWS`
             ${next && `<p class="group-chronology-link">${
-                strings('albumSidebar.groupBox.next', {
+                language.$('albumSidebar.groupBox.next', {
                     album: link.album(next)
                 })
             }</p>`}
             ${previous && `<p class="group-chronology-link">${
-                strings('albumSidebar.groupBox.previous', {
+                language.$('albumSidebar.groupBox.previous', {
                     album: link.album(previous)
                 })
             }</p>`}
@@ -397,8 +397,8 @@ export function generateAlbumNavLinks(album, currentTrack, {
     });
     const randomLink = `<a href="#" data-random="track-in-album" id="random-button">${
         (currentTrack
-            ? strings('trackPage.nav.random')
-            : strings('albumPage.nav.randomTrack'))
+            ? language.$('trackPage.nav.random')
+            : language.$('albumPage.nav.randomTrack'))
     }</a>`;
 
     return (previousNextLinks
diff --git a/src/page/artist.js b/src/page/artist.js
index 0383c68d..3a9de70b 100644
--- a/src/page/artist.js
+++ b/src/page/artist.js
@@ -143,20 +143,20 @@ export function write(artist, {wikiData}) {
         aka, entry, artists, contrib
     }) =>
         (aka
-            ? strings('artistPage.creditList.entry.rerelease', {entry})
+            ? language.$('artistPage.creditList.entry.rerelease', {entry})
             : (artists.length
                 ? ((contrib.what || contrib.whatArray?.length)
-                    ? strings('artistPage.creditList.entry.withArtists.withContribution', {
+                    ? language.$('artistPage.creditList.entry.withArtists.withContribution', {
                         entry,
                         artists: getArtistString(artists),
                         contribution: (contrib.whatArray ? strings.list.unit(contrib.whatArray) : contrib.what)
                     })
-                    : strings('artistPage.creditList.entry.withArtists', {
+                    : language.$('artistPage.creditList.entry.withArtists', {
                         entry,
                         artists: getArtistString(artists)
                     }))
                 : ((contrib.what || contrib.whatArray?.length)
-                    ? strings('artistPage.creditList.entry.withContribution', {
+                    ? language.$('artistPage.creditList.entry.withContribution', {
                         entry,
                         contribution: (contrib.whatArray ? strings.list.unit(contrib.whatArray) : contrib.what)
                     })
@@ -168,24 +168,24 @@ export function write(artist, {wikiData}) {
         <dl>
             ${chunks.map(({date, album, chunk, duration}) => fixWS`
                 <dt>${
-                    (date && duration) ? strings('artistPage.creditList.album.withDate.withDuration', {
+                    (date && duration) ? language.$('artistPage.creditList.album.withDate.withDuration', {
                         album: link.album(album),
                         date: strings.count.date(date),
                         duration: strings.count.duration(duration, {approximate: true})
-                    }) : date ? strings('artistPage.creditList.album.withDate', {
+                    }) : date ? language.$('artistPage.creditList.album.withDate', {
                         album: link.album(album),
                         date: strings.count.date(date)
-                    }) : duration ? strings('artistPage.creditList.album.withDuration', {
+                    }) : duration ? language.$('artistPage.creditList.album.withDuration', {
                         album: link.album(album),
                         duration: strings.count.duration(duration, {approximate: true})
-                    }) : strings('artistPage.creditList.album', {
+                    }) : language.$('artistPage.creditList.album', {
                         album: link.album(album)
                     })}</dt>
                 <dd><ul>
                     ${(chunk
                         .map(({track, ...props}) => ({
                             aka: track.aka,
-                            entry: strings('artistPage.creditList.entry.track.withDuration', {
+                            entry: language.$('artistPage.creditList.entry.track.withDuration', {
                                 track: link.track(track),
                                 duration: strings.count.duration(track.duration)
                             }),
@@ -283,47 +283,47 @@ export function write(artist, {wikiData}) {
             });
 
             return {
-                title: strings('artistPage.title', {artist: name}),
+                title: language.$('artistPage.title', {artist: name}),
 
                 main: {
                     content: fixWS`
                         ${artist.hasAvatar && generateCoverLink({
                             src: getArtistAvatar(artist),
-                            alt: strings('misc.alt.artistAvatar')
+                            alt: language.$('misc.alt.artistAvatar')
                         })}
-                        <h1>${strings('artistPage.title', {artist: name})}</h1>
+                        <h1>${language.$('artistPage.title', {artist: name})}</h1>
                         ${contextNotes && fixWS`
-                            <p>${strings('releaseInfo.note')}</p>
+                            <p>${language.$('releaseInfo.note')}</p>
                             <blockquote>
                                 ${transformMultiline(contextNotes)}
                             </blockquote>
                             <hr>
                         `}
-                        ${urls?.length && `<p>${strings('releaseInfo.visitOn', {
+                        ${urls?.length && `<p>${language.$('releaseInfo.visitOn', {
                             links: strings.list.or(urls.map(url => fancifyURL(url, {strings})))
                         })}</p>`}
-                        ${hasGallery && `<p>${strings('artistPage.viewArtGallery', {
+                        ${hasGallery && `<p>${language.$('artistPage.viewArtGallery', {
                             link: link.artistGallery(artist, {
-                                text: strings('artistPage.viewArtGallery.link')
+                                text: language.$('artistPage.viewArtGallery.link')
                             })
                         })}</p>`}
-                        <p>${strings('misc.jumpTo.withLinks', {
+                        <p>${language.$('misc.jumpTo.withLinks', {
                             links: strings.list.unit([
-                                allTracks.length && `<a href="#tracks">${strings('artistPage.trackList.title')}</a>`,
-                                artThingsAll.length && `<a href="#art">${strings('artistPage.artList.title')}</a>`,
-                                wikiInfo.enableFlashesAndGames && flashes.length && `<a href="#flashes">${strings('artistPage.flashList.title')}</a>`,
-                                commentaryThings.length && `<a href="#commentary">${strings('artistPage.commentaryList.title')}</a>`
+                                allTracks.length && `<a href="#tracks">${language.$('artistPage.trackList.title')}</a>`,
+                                artThingsAll.length && `<a href="#art">${language.$('artistPage.artList.title')}</a>`,
+                                wikiInfo.enableFlashesAndGames && flashes.length && `<a href="#flashes">${language.$('artistPage.flashList.title')}</a>`,
+                                commentaryThings.length && `<a href="#commentary">${language.$('artistPage.commentaryList.title')}</a>`
                             ].filter(Boolean))
                         })}</p>
                         ${allTracks.length && fixWS`
-                            <h2 id="tracks">${strings('artistPage.trackList.title')}</h2>
-                            <p>${strings('artistPage.contributedDurationLine', {
+                            <h2 id="tracks">${language.$('artistPage.trackList.title')}</h2>
+                            <p>${language.$('artistPage.contributedDurationLine', {
                                 artist: artist.name,
                                 duration: strings.count.duration(totalDuration, {approximate: true, unit: true})
                             })}</p>
-                            <p>${strings('artistPage.musicGroupsLine', {
+                            <p>${language.$('artistPage.musicGroupsLine', {
                                 groups: strings.list.unit(musicGroups
-                                    .map(({ group, contributions }) => strings('artistPage.groupsLine.item', {
+                                    .map(({ group, contributions }) => language.$('artistPage.groupsLine.item', {
                                         group: link.groupInfo(group),
                                         contributions: language.countContributions(contributions)
                                     })))
@@ -331,22 +331,22 @@ export function write(artist, {wikiData}) {
                             ${generateTrackList(trackListChunks)}
                         `}
                         ${artThingsAll.length && fixWS`
-                            <h2 id="art">${strings('artistPage.artList.title')}</h2>
-                            ${hasGallery && `<p>${strings('artistPage.viewArtGallery.orBrowseList', {
+                            <h2 id="art">${language.$('artistPage.artList.title')}</h2>
+                            ${hasGallery && `<p>${language.$('artistPage.viewArtGallery.orBrowseList', {
                                 link: link.artistGallery(artist, {
-                                    text: strings('artistPage.viewArtGallery.link')
+                                    text: language.$('artistPage.viewArtGallery.link')
                                 })
                             })}</p>`}
-                            <p>${strings('artistPage.artGroupsLine', {
+                            <p>${language.$('artistPage.artGroupsLine', {
                                 groups: strings.list.unit(artGroups
-                                    .map(({ group, contributions }) => strings('artistPage.groupsLine.item', {
+                                    .map(({ group, contributions }) => language.$('artistPage.groupsLine.item', {
                                         group: link.groupInfo(group),
                                         contributions: language.countContributions(contributions)
                                     })))
                             })}</p>
                             <dl>
                                 ${artListChunks.map(({date, album, chunk}) => fixWS`
-                                    <dt>${strings('artistPage.creditList.album.withDate', {
+                                    <dt>${language.$('artistPage.creditList.album.withDate', {
                                         album: link.album(album),
                                         date: strings.count.date(date)
                                     })}</dt>
@@ -354,10 +354,10 @@ export function write(artist, {wikiData}) {
                                         ${(chunk
                                             .map(({album, track, key, ...props}) => ({
                                                 entry: (track
-                                                    ? strings('artistPage.creditList.entry.track', {
+                                                    ? language.$('artistPage.creditList.entry.track', {
                                                         track: link.track(track)
                                                     })
-                                                    : `<i>${strings('artistPage.creditList.entry.album.' + {
+                                                    : `<i>${language.$('artistPage.creditList.entry.album.' + {
                                                         wallpaperArtistContribs: 'wallpaperArt',
                                                         bannerArtistContribs: 'bannerArt',
                                                         coverArtistContribs: 'coverArt'
@@ -372,17 +372,17 @@ export function write(artist, {wikiData}) {
                             </dl>
                         `}
                         ${wikiInfo.enableFlashesAndGames && flashes.length && fixWS`
-                            <h2 id="flashes">${strings('artistPage.flashList.title')}</h2>
+                            <h2 id="flashes">${language.$('artistPage.flashList.title')}</h2>
                             <dl>
                                 ${flashListChunks.map(({act, chunk, dateFirst, dateLast}) => fixWS`
-                                    <dt>${strings('artistPage.creditList.flashAct.withDateRange', {
+                                    <dt>${language.$('artistPage.creditList.flashAct.withDateRange', {
                                         act: link.flash(chunk[0].flash, {text: act.name}),
                                         dateRange: strings.count.dateRange([dateFirst, dateLast])
                                     })}</dt>
                                     <dd><ul>
                                         ${(chunk
                                             .map(({flash, ...props}) => ({
-                                                entry: strings('artistPage.creditList.entry.flash', {
+                                                entry: language.$('artistPage.creditList.entry.flash', {
                                                     flash: link.flash(flash)
                                                 }),
                                                 ...props
@@ -395,19 +395,19 @@ export function write(artist, {wikiData}) {
                             </dl>
                         `}
                         ${commentaryThings.length && fixWS`
-                            <h2 id="commentary">${strings('artistPage.commentaryList.title')}</h2>
+                            <h2 id="commentary">${language.$('artistPage.commentaryList.title')}</h2>
                             <dl>
                                 ${commentaryListChunks.map(({album, chunk}) => fixWS`
-                                    <dt>${strings('artistPage.creditList.album', {
+                                    <dt>${language.$('artistPage.creditList.album', {
                                         album: link.album(album)
                                     })}</dt>
                                     <dd><ul>
                                         ${(chunk
                                             .map(({album, track, ...props}) => track
-                                                ? strings('artistPage.creditList.entry.track', {
+                                                ? language.$('artistPage.creditList.entry.track', {
                                                     track: link.track(track)
                                                 })
-                                                : `<i>${strings('artistPage.creditList.entry.album.commentary')}</i>`)
+                                                : `<i>${language.$('artistPage.creditList.entry.album.commentary')}</i>`)
                                             .map(row => `<li>${row}</li>`)
                                             .join('\n'))}
                                     </ul></dd>
@@ -439,13 +439,13 @@ export function write(artist, {wikiData}) {
             strings,
             to
         }) => ({
-            title: strings('artistGalleryPage.title', {artist: name}),
+            title: language.$('artistGalleryPage.title', {artist: name}),
 
             main: {
                 classes: ['top-index'],
                 content: fixWS`
-                    <h1>${strings('artistGalleryPage.title', {artist: name})}</h1>
-                    <p class="quick-info">${strings('artistGalleryPage.infoLine', {
+                    <h1>${language.$('artistGalleryPage.title', {artist: name})}</h1>
+                    <p class="quick-info">${language.$('artistGalleryPage.infoLine', {
                         coverArts: language.countCoverArts(artThingsGallery.length, {unit: true})
                     })}</p>
                     <div class="grid-listing">
@@ -497,10 +497,10 @@ function generateNavForArtist(artist, isGallery, hasGallery, {
             wikiInfo.enableListings &&
             {
                 path: ['localized.listingIndex'],
-                title: strings('listingIndex.title')
+                title: language.$('listingIndex.title')
             },
             {
-                html: strings('artistPage.nav.artist', {
+                html: language.$('artistPage.nav.artist', {
                     artist: link.artist(artist, {class: 'current'})
                 })
             },
diff --git a/src/page/flash.js b/src/page/flash.js
index 54653a00..5e027f70 100644
--- a/src/page/flash.js
+++ b/src/page/flash.js
@@ -36,20 +36,20 @@ export function write(flash, {wikiData}) {
             strings,
             transformInline
         }) => ({
-            title: strings('flashPage.title', {flash: flash.name}),
+            title: language.$('flashPage.title', {flash: flash.name}),
             theme: getThemeString(flash.color, [
                 `--flash-directory: ${flash.directory}`
             ]),
 
             main: {
                 content: fixWS`
-                    <h1>${strings('flashPage.title', {flash: flash.name})}</h1>
+                    <h1>${language.$('flashPage.title', {flash: flash.name})}</h1>
                     ${generateCoverLink({
                         src: getFlashCover(flash),
-                        alt: strings('misc.alt.flashArt')
+                        alt: language.$('misc.alt.flashArt')
                     })}
-                    <p>${strings('releaseInfo.released', {date: strings.count.date(flash.date)})}</p>
-                    ${(flash.page || flash.urls?.length) && `<p>${strings('releaseInfo.playOn', {
+                    <p>${language.$('releaseInfo.released', {date: strings.count.date(flash.date)})}</p>
+                    ${(flash.page || flash.urls?.length) && `<p>${language.$('releaseInfo.playOn', {
                         links: strings.list.or([
                             flash.page && getFlashLink(flash),
                             ...flash.urls ?? []
@@ -59,10 +59,10 @@ export function write(flash, {wikiData}) {
                         <p>Tracks featured in <i>${flash.name.replace(/\.$/, '')}</i>:</p>
                         <ul>
                             ${(flash.featuredTracks
-                                .map(track => strings('trackList.item.withArtists', {
+                                .map(track => language.$('trackList.item.withArtists', {
                                     track: link.track(track),
                                     by: `<span class="by">${
-                                        strings('trackList.item.withArtists.by', {
+                                        language.$('trackList.item.withArtists.by', {
                                             artists: getArtistString(track.artistContribs)
                                         })
                                     }</span>`
@@ -72,7 +72,7 @@ export function write(flash, {wikiData}) {
                         </ul>
                     `}
                     ${flash.contributorContribs.length && fixWS`
-                        <p>${strings('releaseInfo.contributors')}</p>
+                        <p>${language.$('releaseInfo.contributors')}</p>
                         <ul>
                             ${flash.contributorContribs
                                 .map(contrib => `<li>${getArtistString([contrib], {
@@ -111,14 +111,14 @@ export function writeTargetless({wikiData}) {
             link,
             strings
         }) => ({
-            title: strings('flashIndex.title'),
+            title: language.$('flashIndex.title'),
 
             main: {
                 classes: ['flash-index'],
                 content: fixWS`
-                    <h1>${strings('flashIndex.title')}</h1>
+                    <h1>${language.$('flashIndex.title')}</h1>
                     <div class="long-content">
-                        <p class="quick-info">${strings('misc.jumpTo')}</p>
+                        <p class="quick-info">${language.$('misc.jumpTo')}</p>
                         <ul class="quick-info">
                             ${flashActData.filter(act => act.jump).map(({ anchor, jump, jumpColor }) => fixWS`
                                 <li><a href="#${anchor}" style="${getLinkThemeString(jumpColor)}">${jump}</a></li>
@@ -165,10 +165,10 @@ function generateNavForFlash(flash, {
             {toHome: true},
             {
                 path: ['localized.flashIndex'],
-                title: strings('flashIndex.title')
+                title: language.$('flashIndex.title')
             },
             {
-                html: strings('flashPage.nav.flash', {
+                html: language.$('flashPage.nav.flash', {
                     flash: link.flash(flash, {class: 'current'})
                 })
             },
@@ -211,7 +211,7 @@ function generateSidebarForFlash(flash, {link, strings, wikiData}) {
 
     return {
         content: fixWS`
-            <h1>${link.flashIndex('', {text: strings('flashIndex.title')})}</h1>
+            <h1>${link.flashIndex('', {text: language.$('flashIndex.title')})}</h1>
             <dl>
                 ${flashActData.filter(act =>
                     act.name.startsWith('Act 1') ||
diff --git a/src/page/group.js b/src/page/group.js
index 7ffade67..53c792a4 100644
--- a/src/page/group.js
+++ b/src/page/group.js
@@ -42,44 +42,44 @@ export function write(group, {wikiData}) {
             strings,
             transformMultiline
         }) => ({
-            title: strings('groupInfoPage.title', {group: group.name}),
+            title: language.$('groupInfoPage.title', {group: group.name}),
             theme: getThemeString(group.color),
 
             main: {
                 content: fixWS`
-                    <h1>${strings('groupInfoPage.title', {group: group.name})}</h1>
+                    <h1>${language.$('groupInfoPage.title', {group: group.name})}</h1>
                     ${group.urls?.length && `<p>${
-                        strings('releaseInfo.visitOn', {
+                        language.$('releaseInfo.visitOn', {
                             links: strings.list.or(group.urls.map(url => fancifyURL(url, {strings})))
                         })
                     }</p>`}
                     <blockquote>
                         ${transformMultiline(group.description)}
                     </blockquote>
-                    <h2>${strings('groupInfoPage.albumList.title')}</h2>
+                    <h2>${language.$('groupInfoPage.albumList.title')}</h2>
                     <p>${
-                        strings('groupInfoPage.viewAlbumGallery', {
+                        language.$('groupInfoPage.viewAlbumGallery', {
                             link: link.groupGallery(group, {
-                                text: strings('groupInfoPage.viewAlbumGallery.link')
+                                text: language.$('groupInfoPage.viewAlbumGallery.link')
                             })
                         })
                     }</p>
                     <ul>
                         ${albumLines.map(({ album, otherGroup }) => {
                             const item = (album.date
-                                ? strings('groupInfoPage.albumList.item', {
+                                ? language.$('groupInfoPage.albumList.item', {
                                     year: album.date.getFullYear(),
                                     album: link.album(album)
                                 })
-                                : strings('groupInfoPage.albumList.item.withoutYear', {
+                                : language.$('groupInfoPage.albumList.item.withoutYear', {
                                     album: link.album(album)
                                 }));
                             return html.tag('li', (otherGroup
-                                ? strings('groupInfoPage.albumList.item.withAccent', {
+                                ? language.$('groupInfoPage.albumList.item.withAccent', {
                                     item,
                                     accent: html.tag('span',
                                         {class: 'other-group-accent'},
-                                        strings('groupInfoPage.albumList.item.otherGroupAccent', {
+                                        language.$('groupInfoPage.albumList.item.otherGroupAccent', {
                                             group: link.groupInfo(otherGroup, {color: false})
                                         }))
                                 })
@@ -118,15 +118,15 @@ export function write(group, {wikiData}) {
             link,
             strings
         }) => ({
-            title: strings('groupGalleryPage.title', {group: group.name}),
+            title: language.$('groupGalleryPage.title', {group: group.name}),
             theme: getThemeString(group.color),
 
             main: {
                 classes: ['top-index'],
                 content: fixWS`
-                    <h1>${strings('groupGalleryPage.title', {group: group.name})}</h1>
+                    <h1>${language.$('groupGalleryPage.title', {group: group.name})}</h1>
                     <p class="quick-info">${
-                        strings('groupGalleryPage.infoLine', {
+                        language.$('groupGalleryPage.infoLine', {
                             tracks: `<b>${language.countTracks(tracks.length, {unit: true})}</b>`,
                             albums: `<b>${language.countAlbums(albums.length, {unit: true})}</b>`,
                             time: `<b>${strings.count.duration(totalDuration, {unit: true})}</b>`
@@ -134,9 +134,9 @@ export function write(group, {wikiData}) {
                     }</p>
                     ${wikiInfo.enableGroupUI && wikiInfo.enableListings && html.tag('p',
                         {class: 'quick-info'},
-                        strings('groupGalleryPage.anotherGroupLine', {
+                        language.$('groupGalleryPage.anotherGroupLine', {
                             link: link.listing(listingSpec.find(l => l.directory === 'groups/by-category'), {
-                                text: strings('groupGalleryPage.anotherGroupLine.link')
+                                text: language.$('groupGalleryPage.anotherGroupLine.link')
                             })
                         })
                     )}
@@ -187,7 +187,7 @@ function generateGroupSidebar(currentGroup, isGallery, {
 
     return {
         content: fixWS`
-            <h1>${strings('groupSidebar.title')}</h1>
+            <h1>${language.$('groupSidebar.title')}</h1>
             ${groupCategoryData.map(category =>
                 html.tag('details', {
                     open: category === currentGroup.category,
@@ -195,7 +195,7 @@ function generateGroupSidebar(currentGroup, isGallery, {
                 }, [
                     html.tag('summary',
                         {style: getLinkThemeString(category.color)},
-                        strings('groupSidebar.groupList.category', {
+                        language.$('groupSidebar.groupList.category', {
                             category: `<span class="group-name">${category.name}</span>`
                         })),
                     html.tag('ul',
@@ -204,7 +204,7 @@ function generateGroupSidebar(currentGroup, isGallery, {
                                 class: group === currentGroup && 'current',
                                 style: getLinkThemeString(group.color)
                             },
-                            strings('groupSidebar.groupList.item', {
+                            language.$('groupSidebar.groupList.item', {
                                 group: link[linkKey](group)
                             }))))
                 ])).join('\n')}
@@ -245,10 +245,10 @@ function generateGroupNav(currentGroup, isGallery, {
             wikiInfo.enableListings &&
             {
                 path: ['localized.listingIndex'],
-                title: strings('listingIndex.title')
+                title: language.$('listingIndex.title')
             },
             {
-                html: strings('groupPage.nav.group', {
+                html: language.$('groupPage.nav.group', {
                     group: link[linkKey](currentGroup, {class: 'current'})
                 })
             },
diff --git a/src/page/homepage.js b/src/page/homepage.js
index 8b470e9b..ed7d3442 100644
--- a/src/page/homepage.js
+++ b/src/page/homepage.js
@@ -84,14 +84,14 @@ export function writeTargetless({wikiData}) {
                 // (even though that would 8e hilarious).
                 content: (transformMultiline(homepageLayout.sidebarContent.replace('[[news]]', '__GENERATE_NEWS__'))
                     .replace('<p>__GENERATE_NEWS__</p>', wikiInfo.enableNews ? fixWS`
-                        <h1>${strings('homepage.news.title')}</h1>
+                        <h1>${language.$('homepage.news.title')}</h1>
                         ${newsData.slice(0, 3).map((entry, i) => html.tag('article',
                             {class: ['news-entry', i === 0 && 'first-news-entry']},
                             fixWS`
                                 <h2><time>${strings.count.date(entry.date)}</time> ${link.newsEntry(entry)}</h2>
                                 ${transformMultiline(entry.contentShort)}
                                 ${entry.contentShort !== entry.content && link.newsEntry(entry, {
-                                    text: strings('homepage.news.entry.viewRest')
+                                    text: language.$('homepage.news.entry.viewRest')
                                 })}
                             `)).join('\n')}
                     ` : `<p><i>News requested in content description but this feature isn't enabled</i></p>`))
@@ -103,11 +103,11 @@ export function writeTargetless({wikiData}) {
                         ${[
                             link.home('', {text: wikiInfo.nameShort, class: 'current', to}),
                             wikiInfo.enableListings &&
-                            link.listingIndex('', {text: strings('listingIndex.title'), to}),
+                            link.listingIndex('', {text: language.$('listingIndex.title'), to}),
                             wikiInfo.enableNews &&
-                            link.newsIndex('', {text: strings('newsIndex.title'), to}),
+                            link.newsIndex('', {text: language.$('newsIndex.title'), to}),
                             wikiInfo.enableFlashesAndGames &&
-                            link.flashIndex('', {text: strings('flashIndex.title'), to}),
+                            link.flashIndex('', {text: language.$('flashIndex.title'), to}),
                             ...(staticPageData
                                 .filter(page => page.showInNavigationBar)
                                 .map(page => link.staticPage(page, {text: page.nameShort})))
diff --git a/src/page/listing.js b/src/page/listing.js
index dbac4b73..efa3fdfd 100644
--- a/src/page/listing.js
+++ b/src/page/listing.js
@@ -47,11 +47,11 @@ export function write(listing, {wikiData}) {
             const titleKey = `listingPage.${listing.stringsKey}.title`;
 
             return {
-                title: strings(titleKey),
+                title: language.$(titleKey),
 
                 main: {
                     content: fixWS`
-                        <h1>${strings(titleKey)}</h1>
+                        <h1>${language.$(titleKey)}</h1>
                         ${listing.html && (listing.data
                             ? listing.html(data, opts)
                             : listing.html(opts))}
@@ -80,7 +80,7 @@ export function write(listing, {wikiData}) {
                         {toHome: true},
                         {
                             path: ['localized.listingIndex'],
-                            title: strings('listingIndex.title')
+                            title: language.$('listingIndex.title')
                         },
                         {toCurrentPage: true}
                     ]
@@ -105,19 +105,19 @@ export function writeTargetless({wikiData}) {
             strings,
             link
         }) => ({
-            title: strings('listingIndex.title'),
+            title: language.$('listingIndex.title'),
 
             main: {
                 content: fixWS`
-                    <h1>${strings('listingIndex.title')}</h1>
-                    <p>${strings('listingIndex.infoLine', {
+                    <h1>${language.$('listingIndex.title')}</h1>
+                    <p>${language.$('listingIndex.infoLine', {
                         wiki: wikiInfo.name,
                         tracks: `<b>${language.countTracks(trackData.length, {unit: true})}</b>`,
                         albums: `<b>${language.countAlbums(albumData.length, {unit: true})}</b>`,
                         duration: `<b>${strings.count.duration(totalDuration, {approximate: true, unit: true})}</b>`
                     })}</p>
                     <hr>
-                    <p>${strings('listingIndex.exploreList')}</p>
+                    <p>${language.$('listingIndex.exploreList')}</p>
                     ${generateLinkIndexForListings(null, false, {link, strings, wikiData})}
                 `
             },
@@ -147,7 +147,7 @@ function generateSidebarForListings(currentListing, {
     wikiData
 }) {
     return fixWS`
-        <h1>${link.listingIndex('', {text: strings('listingIndex.title')})}</h1>
+        <h1>${link.listingIndex('', {text: language.$('listingIndex.title')})}</h1>
         ${generateLinkIndexForListings(currentListing, true, {
             getLinkThemeString,
             link,
@@ -175,7 +175,7 @@ function generateLinkIndexForListings(currentListing, forSidebar, {
     const genUL = listings => html.tag('ul',
         listings.map(listing => html.tag('li',
             {class: [listing === currentListing && 'current']},
-            link.listing(listing, {text: strings(`listingPage.${listing.stringsKey}.title.short`)})
+            link.listing(listing, {text: language.$(`listingPage.${listing.stringsKey}.title.short`)})
         )));
 
     if (forSidebar) {
diff --git a/src/page/news.js b/src/page/news.js
index 759bb93b..9951a2a8 100644
--- a/src/page/news.js
+++ b/src/page/news.js
@@ -24,13 +24,13 @@ export function write(entry, {wikiData}) {
             strings,
             transformMultiline,
         }) => ({
-            title: strings('newsEntryPage.title', {entry: entry.name}),
+            title: language.$('newsEntryPage.title', {entry: entry.name}),
 
             main: {
                 content: fixWS`
                     <div class="long-content">
-                        <h1>${strings('newsEntryPage.title', {entry: entry.name})}</h1>
-                        <p>${strings('newsEntryPage.published', {date: strings.count.date(entry.date)})}</p>
+                        <h1>${language.$('newsEntryPage.title', {entry: entry.name})}</h1>
+                        <p>${language.$('newsEntryPage.published', {date: strings.count.date(entry.date)})}</p>
                         ${transformMultiline(entry.content)}
                     </div>
                 `
@@ -59,18 +59,18 @@ export function writeTargetless({wikiData}) {
             strings,
             transformMultiline
         }) => ({
-            title: strings('newsIndex.title'),
+            title: language.$('newsIndex.title'),
 
             main: {
                 content: fixWS`
                     <div class="long-content news-index">
-                        <h1>${strings('newsIndex.title')}</h1>
+                        <h1>${language.$('newsIndex.title')}</h1>
                         ${newsData.map(entry => fixWS`
                             <article id="${entry.directory}">
                                 <h2><time>${strings.count.date(entry.date)}</time> ${link.newsEntry(entry)}</h2>
                                 ${transformMultiline(entry.contentShort)}
                                 ${entry.contentShort !== entry.content && `<p>${link.newsEntry(entry, {
-                                    text: strings('newsIndex.entry.viewRest')
+                                    text: language.$('newsIndex.entry.viewRest')
                                 })}</p>`}
                             </article>
                         `).join('\n')}
@@ -108,10 +108,10 @@ function generateNewsEntryNav(entry, {
             {toHome: true},
             {
                 path: ['localized.newsIndex'],
-                title: strings('newsEntryPage.nav.news')
+                title: language.$('newsEntryPage.nav.news')
             },
             {
-                html: strings('newsEntryPage.nav.entry', {
+                html: language.$('newsEntryPage.nav.entry', {
                     date: strings.count.date(entry.date),
                     entry: link.newsEntry(entry, {class: 'current'})
                 })
diff --git a/src/page/tag.js b/src/page/tag.js
index 09d0beb9..af2e3942 100644
--- a/src/page/tag.js
+++ b/src/page/tag.js
@@ -37,14 +37,14 @@ export function write(tag, {wikiData}) {
             strings,
             to
         }) => ({
-            title: strings('tagPage.title', {tag: tag.name}),
+            title: language.$('tagPage.title', {tag: tag.name}),
             theme: getThemeString(tag.color),
 
             main: {
                 classes: ['top-index'],
                 content: fixWS`
-                    <h1>${strings('tagPage.title', {tag: tag.name})}</h1>
-                    <p class="quick-info">${strings('tagPage.infoLine', {
+                    <h1>${language.$('tagPage.title', {tag: tag.name})}</h1>
+                    <p class="quick-info">${language.$('tagPage.infoLine', {
                         coverArts: language.countCoverArts(things.length, {unit: true})
                     })}</p>
                     <div class="grid-listing">
@@ -92,10 +92,10 @@ function generateTagNav(tag, {
             wikiData.wikiInfo.enableListings &&
             {
                 path: ['localized.listingIndex'],
-                title: strings('listingIndex.title')
+                title: language.$('listingIndex.title')
             },
             {
-                html: strings('tagPage.nav.tag', {
+                html: language.$('tagPage.nav.tag', {
                     tag: link.tag(tag, {class: 'current'})
                 })
             },
diff --git a/src/page/track.js b/src/page/track.js
index c27b2b65..92a49ff0 100644
--- a/src/page/track.js
+++ b/src/page/track.js
@@ -52,14 +52,14 @@ export function write(track, {wikiData}) {
 
     const unbound_generateTrackList = (tracks, {getArtistString, link, strings}) => html.tag('ul',
         tracks.map(track => {
-            const line = strings('trackList.item.withArtists', {
+            const line = language.$('trackList.item.withArtists', {
                 track: link.track(track),
-                by: `<span class="by">${strings('trackList.item.withArtists.by', {
+                by: `<span class="by">${language.$('trackList.item.withArtists.by', {
                     artists: getArtistString(track.artistContribs)
                 })}</span>`
             });
             return (track.aka
-                ? `<li class="rerelease">${strings('trackList.item.rerelease', {track: line})}</li>`
+                ? `<li class="rerelease">${language.$('trackList.item.rerelease', {track: line})}</li>`
                 : `<li>${line}</li>`);
         })
     );
@@ -76,7 +76,7 @@ export function write(track, {wikiData}) {
                 .filter(line => line.replace(/<\/b>/g, '').includes(':</i>'))
                 .map(line => fixWS`
                     ${line}
-                    ${strings('releaseInfo.artistCommentary.seeOriginalRelease', {
+                    ${language.$('releaseInfo.artistCommentary.seeOriginalRelease', {
                         original: link.track(track)
                     })}
                 `)
@@ -140,7 +140,7 @@ export function write(track, {wikiData}) {
             const cover = getTrackCover(track);
 
             return {
-                title: strings('trackPage.title', {track: track.name}),
+                title: language.$('trackPage.title', {track: track.name}),
                 stylesheet: getAlbumStylesheet(album, {to}),
                 theme: getThemeString(track.color, [
                     `--album-directory: ${album.directory}`,
@@ -153,7 +153,7 @@ export function write(track, {wikiData}) {
                     classes: ['dim'],
                     dimensions: album.bannerDimensions,
                     path: ['media.albumBanner', album.directory, album.bannerFileExtension],
-                    alt: strings('misc.alt.albumBanner'),
+                    alt: language.$('misc.alt.albumBanner'),
                     position: 'bottom'
                 },
                 */
@@ -162,49 +162,49 @@ export function write(track, {wikiData}) {
                     content: fixWS`
                         ${cover && generateCoverLink({
                             src: cover,
-                            alt: strings('misc.alt.trackCover'),
+                            alt: language.$('misc.alt.trackCover'),
                             tags: track.artTags
                         })}
-                        <h1>${strings('trackPage.title', {track: track.name})}</h1>
+                        <h1>${language.$('trackPage.title', {track: track.name})}</h1>
                         <p>
                             ${[
-                                strings('releaseInfo.by', {
+                                language.$('releaseInfo.by', {
                                     artists: getArtistString(track.artistContribs, {
                                         showContrib: true,
                                         showIcons: true
                                     })
                                 }),
-                                track.coverArtistContribs.length && strings('releaseInfo.coverArtBy', {
+                                track.coverArtistContribs.length && language.$('releaseInfo.coverArtBy', {
                                     artists: getArtistString(track.coverArtistContribs, {
                                         showContrib: true,
                                         showIcons: true
                                     })
                                 }),
-                                track.date && strings('releaseInfo.released', {
+                                track.date && language.$('releaseInfo.released', {
                                     date: strings.count.date(track.date)
                                 }),
                                 (track.coverArtDate &&
                                     +track.coverArtDate !== +track.date &&
-                                    strings('releaseInfo.artReleased', {
+                                    language.$('releaseInfo.artReleased', {
                                         date: strings.count.date(track.coverArtDate)
                                     })),
-                                track.duration && strings('releaseInfo.duration', {
+                                track.duration && language.$('releaseInfo.duration', {
                                     duration: strings.count.duration(track.duration)
                                 })
                             ].filter(Boolean).join('<br>\n')}
                         </p>
                         <p>${
                             (track.urls?.length
-                                ? strings('releaseInfo.listenOn', {
+                                ? language.$('releaseInfo.listenOn', {
                                     links: strings.list.or(track.urls.map(url => fancifyURL(url, {strings})))
                                 })
-                                : strings('releaseInfo.listenOn.noLinks'))
+                                : language.$('releaseInfo.listenOn.noLinks'))
                         }</p>
                         ${otherReleases.length && fixWS`
-                            <p>${strings('releaseInfo.alsoReleasedAs')}</p>
+                            <p>${language.$('releaseInfo.alsoReleasedAs')}</p>
                             <ul>
                                 ${otherReleases.map(track => fixWS`
-                                    <li>${strings('releaseInfo.alsoReleasedAs.item', {
+                                    <li>${language.$('releaseInfo.alsoReleasedAs.item', {
                                         track: link.track(track),
                                         album: link.album(track.album)
                                     })}</li>
@@ -212,7 +212,7 @@ export function write(track, {wikiData}) {
                             </ul>
                         `}
                         ${track.contributorContribs.length && fixWS`
-                            <p>${strings('releaseInfo.contributors')}</p>
+                            <p>${language.$('releaseInfo.contributors')}</p>
                             <ul>
                                 ${(track.contributorContribs
                                     .map(contrib => `<li>${getArtistString([contrib], {
@@ -223,19 +223,19 @@ export function write(track, {wikiData}) {
                             </ul>
                         `}
                         ${referencedTracks.length && fixWS`
-                            <p>${strings('releaseInfo.tracksReferenced', {track: `<i>${track.name}</i>`})}</p>
+                            <p>${language.$('releaseInfo.tracksReferenced', {track: `<i>${track.name}</i>`})}</p>
                             ${generateTrackList(referencedTracks)}
                         `}
                         ${referencedByTracks.length && fixWS`
-                            <p>${strings('releaseInfo.tracksThatReference', {track: `<i>${track.name}</i>`})}</p>
+                            <p>${language.$('releaseInfo.tracksThatReference', {track: `<i>${track.name}</i>`})}</p>
                             ${useDividedReferences && fixWS`
                                 <dl>
                                     ${rbtOfficial.length && fixWS`
-                                        <dt>${strings('trackPage.referenceList.official')}</dt>
+                                        <dt>${language.$('trackPage.referenceList.official')}</dt>
                                         <dd>${generateTrackList(rbtOfficial)}</dd>
                                     `}
                                     ${rbtFanon.length && fixWS`
-                                        <dt>${strings('trackPage.referenceList.fandom')}</dt>
+                                        <dt>${language.$('trackPage.referenceList.fandom')}</dt>
                                         <dd>${generateTrackList(rbtFanon)}</dd>
                                     `}
                                 </dl>
@@ -243,28 +243,28 @@ export function write(track, {wikiData}) {
                             ${!useDividedReferences && generateTrackList(referencedByTracks)}
                         `}
                         ${wikiInfo.enableFlashesAndGames && flashesThatFeature.length && fixWS`
-                            <p>${strings('releaseInfo.flashesThatFeature', {track: `<i>${track.name}</i>`})}</p>
+                            <p>${language.$('releaseInfo.flashesThatFeature', {track: `<i>${track.name}</i>`})}</p>
                             <ul>
                                 ${flashesThatFeature.map(({ flash, as }) => html.tag('li',
                                     {class: as !== track && 'rerelease'},
                                     (as === track
-                                        ? strings('releaseInfo.flashesThatFeature.item', {
+                                        ? language.$('releaseInfo.flashesThatFeature.item', {
                                             flash: link.flash(flash)
                                         })
-                                        : strings('releaseInfo.flashesThatFeature.item.asDifferentRelease', {
+                                        : language.$('releaseInfo.flashesThatFeature.item.asDifferentRelease', {
                                             flash: link.flash(flash),
                                             track: link.track(as)
                                         })))).join('\n')}
                             </ul>
                         `}
                         ${track.lyrics && fixWS`
-                            <p>${strings('releaseInfo.lyrics')}</p>
+                            <p>${language.$('releaseInfo.lyrics')}</p>
                             <blockquote>
                                 ${transformLyrics(track.lyrics)}
                             </blockquote>
                         `}
                         ${hasCommentary && fixWS`
-                            <p>${strings('releaseInfo.artistCommentary')}</p>
+                            <p>${language.$('releaseInfo.artistCommentary')}</p>
                             <blockquote>
                                 ${generateCommentary({link, strings, transformMultiline})}
                             </blockquote>
@@ -289,12 +289,12 @@ export function write(track, {wikiData}) {
                             title: album.name
                         },
                         listTag === 'ol' ? {
-                            html: strings('trackPage.nav.track.withNumber', {
+                            html: language.$('trackPage.nav.track.withNumber', {
                                 number: album.tracks.indexOf(track) + 1,
                                 track: link.track(track, {class: 'current', to})
                             })
                         } : {
-                            html: strings('trackPage.nav.track', {
+                            html: language.$('trackPage.nav.track', {
                                 track: link.track(track, {class: 'current', to})
                             })
                         },
diff --git a/src/upd8.js b/src/upd8.js
index 33c40677..d0df62fc 100755
--- a/src/upd8.js
+++ b/src/upd8.js
@@ -311,7 +311,7 @@ const replacerSpec = {
     'string': {
         find: null,
         value: ref => ref,
-        html: (ref, {strings, args}) => strings(ref, args)
+        html: (ref, {strings, args}) => language.$(ref, args)
     },
     'tag': {
         find: 'artTag',
@@ -1049,9 +1049,9 @@ writePage.html = (pageFn, {
                         })}
                     </div>
                     <h1 class="info-card-name"><a></a></h1>
-                    <p class="info-card-album">${strings('releaseInfo.from', {album: '<a></a>'})}</p>
-                    <p class="info-card-artists">${strings('releaseInfo.by', {artists: '<span></span>'})}</p>
-                    <p class="info-card-cover-artists">${strings('releaseInfo.coverArtBy', {artists: '<span></span>'})}</p>
+                    <p class="info-card-album">${language.$('releaseInfo.from', {album: '<a></a>'})}</p>
+                    <p class="info-card-artists">${language.$('releaseInfo.by', {artists: '<span></span>'})}</p>
+                    <p class="info-card-cover-artists">${language.$('releaseInfo.coverArtBy', {artists: '<span></span>'})}</p>
                 </div>
             </div>
         </div>
@@ -1087,14 +1087,14 @@ writePage.html = (pageFn, {
                     ${mainHTML && fixWS`
                         <div id="skippers">
                             ${[
-                                ['#content', strings('misc.skippers.skipToContent')],
+                                ['#content', language.$('misc.skippers.skipToContent')],
                                 sidebarLeftHTML && ['#sidebar-left', (sidebarRightHTML
-                                    ? strings('misc.skippers.skipToSidebar.left')
-                                    : strings('misc.skippers.skipToSidebar'))],
+                                    ? language.$('misc.skippers.skipToSidebar.left')
+                                    : language.$('misc.skippers.skipToSidebar'))],
                                 sidebarRightHTML && ['#sidebar-right', (sidebarLeftHTML
-                                    ? strings('misc.skippers.skipToSidebar.right')
-                                    : strings('misc.skippers.skipToSidebar'))],
-                                footerHTML && ['#footer', strings('misc.skippers.skipToFooter')]
+                                    ? language.$('misc.skippers.skipToSidebar.right')
+                                    : language.$('misc.skippers.skipToSidebar'))],
+                                footerHTML && ['#footer', language.$('misc.skippers.skipToFooter')]
                             ].filter(Boolean).map(([ href, title ]) => fixWS`
                                 <span class="skipper"><a href="${href}">${title}</a></span>
                             `).join('\n')}
@@ -1201,7 +1201,7 @@ function generateRedirectPage(title, target, {strings}) {
         <!DOCTYPE html>
         <html>
             <head>
-                <title>${strings('redirectPage.title', {title})}</title>
+                <title>${language.$('redirectPage.title', {title})}</title>
                 <meta charset="utf-8">
                 <meta http-equiv="refresh" content="0;url=${target}">
                 <link rel="canonical" href="${target}">
@@ -1209,8 +1209,8 @@ function generateRedirectPage(title, target, {strings}) {
             </head>
             <body>
                 <main>
-                    <h1>${strings('redirectPage.title', {title})}</h1>
-                    <p>${strings('redirectPage.infoLine', {
+                    <h1>${language.$('redirectPage.title', {title})}</h1>
+                    <p>${language.$('redirectPage.infoLine', {
                         target: `<a href="${target}">${target}</a>`
                     })}</p>
                 </main>
diff --git a/src/util/strings.js b/src/util/strings.js
index c596bd89..835e4055 100644
--- a/src/util/strings.js
+++ b/src/util/strings.js
@@ -22,8 +22,8 @@ import { bindOpts } from './sugar.js';
 // look like a dictionary each value of which is itself a util dictionary,
 // each value of which is a function in the format (value, opts) => (...).
 // Each of those util dictionaries will 8e attached to the final returned
-// strings() function, containing functions which automatically have that
-// same strings() function provided as part of its opts argument (alongside
+// language.$() function, containing functions which automatically have that
+// same language.$() function provided as part of its opts argument (alongside
 // any additional arguments passed).
 //
 // Basically, it's so that instead of doing:
@@ -193,7 +193,7 @@ export function genStrings(stringsJSON, {
     return strings;
 }
 
-const countHelper = (stringKey, argName = stringKey) => (value, {strings, unit = false}) => strings(
+const countHelper = (stringKey, argName = stringKey) => (value, {strings, unit = false}) => language.$(
     (unit
         ? `count.${stringKey}.withUnit.` + strings.intl.plural.cardinal.select(value)
         : `count.${stringKey}`),
@@ -222,10 +222,10 @@ export const count = {
             : value);
 
         const words = (value > 1000
-            ? strings('count.words.thousand', {words: num})
-            : strings('count.words', {words: num}));
+            ? language.$('count.words.thousand', {words: num})
+            : language.$('count.words', {words: num}));
 
-        return strings('count.words.withUnit.' + strings.intl.plural.cardinal.select(value), {words});
+        return language.$('count.words.withUnit.' + strings.intl.plural.cardinal.select(value), {words});
     },
 
     albums: countHelper('albums'),