diff --git a/Dockerfile b/Dockerfile
index 8235b5659115..6ebd4a9adf3a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -42,7 +42,7 @@ COPY --chown=node:node --from=install /usr/src/docs/dist /usr/src/docs/dist
ENV NODE_ENV production
# Use Lunr instead of Algolia
-ENV USE_LUNR true
+ENV AIRGAP true
# Copy only what's needed to run the server
COPY --chown=node:node assets ./assets
diff --git a/includes/explorer.html b/includes/explorer.html
index 5f92811dd05a..f471ef3054c8 100644
--- a/includes/explorer.html
+++ b/includes/explorer.html
@@ -1,7 +1,11 @@
{% include breadcrumbs %}
-
+ {% if process.env.AIRGAP %}
+
GraphQL explorer is not available on this environment.
+ {% else %}
+
+ {% endif %}
diff --git a/includes/scripts.html b/includes/scripts.html
index 77555622b2b9..6f328a0cc308 100644
--- a/includes/scripts.html
+++ b/includes/scripts.html
@@ -1,2 +1,2 @@
-
+
diff --git a/javascripts/airgap-links.js b/javascripts/airgap-links.js
new file mode 100644
index 000000000000..b881bde1bd35
--- /dev/null
+++ b/javascripts/airgap-links.js
@@ -0,0 +1,14 @@
+export default function airgapLinks () {
+ // When in an airgapped environment,
+ // show a tooltip on external links
+ const { airgap } = JSON.parse(document.getElementById('expose').text)
+ if (!airgap) return
+
+ const externaLinks = Array.from(
+ document.querySelectorAll('a[href^="http"], a[href^="//"]')
+ )
+ externaLinks.forEach(link => {
+ link.classList.add('tooltipped')
+ link.setAttribute('aria-label', 'This link may not work in this environment.')
+ })
+}
diff --git a/javascripts/index.js b/javascripts/index.js
index ea96ef7d1d84..7cc42b0042b2 100644
--- a/javascripts/index.js
+++ b/javascripts/index.js
@@ -18,6 +18,7 @@ import allArticles from './all-articles'
import devToc from './dev-toc'
import releaseNotes from './release-notes'
import showMore from './show-more'
+import airgapLinks from './airgap-links'
document.addEventListener('DOMContentLoaded', async () => {
displayPlatformSpecificContent()
@@ -34,6 +35,7 @@ document.addEventListener('DOMContentLoaded', async () => {
allArticles()
devToc()
showMore()
+ airgapLinks()
releaseNotes()
initializeEvents()
experiment()
diff --git a/javascripts/search.js b/javascripts/search.js
index cabee3a9fbfe..760bce874bbb 100644
--- a/javascripts/search.js
+++ b/javascripts/search.js
@@ -26,7 +26,7 @@ export default function search () {
languages,
versions,
nonEnterpriseDefaultVersion
- } = JSON.parse(document.getElementById('search-options').text)
+ } = JSON.parse(document.getElementById('expose').text).searchOptions
version = deriveVersionFromPath(versions, nonEnterpriseDefaultVersion)
language = deriveLanguageCodeFromPath(languages)
diff --git a/layouts/graphql-explorer.html b/layouts/graphql-explorer.html
index 7f61637049ba..4b27a9c47c9d 100644
--- a/layouts/graphql-explorer.html
+++ b/layouts/graphql-explorer.html
@@ -20,9 +20,13 @@ {{ page.title }}
-
+ {% if process.env.AIRGAP %}
+
GraphQL explorer is not available on this environment.
+ {% else %}
+
+ {% endif %}
diff --git a/layouts/product-landing.html b/layouts/product-landing.html
index d9d3e00ee9e2..fbda1d83343c 100644
--- a/layouts/product-landing.html
+++ b/layouts/product-landing.html
@@ -41,13 +41,15 @@
{% if page.product_video %}
-
+ {% unless process.env.AIRGAP %}
+
+ {% endunless %}
{% endif %}
diff --git a/lib/search/sync.js b/lib/search/sync.js
index 58168b686cdd..827d47ed7953 100644
--- a/lib/search/sync.js
+++ b/lib/search/sync.js
@@ -71,7 +71,7 @@ module.exports = async function syncSearchIndexes (opts = {}) {
// The page version will be the new version, e.g., free-pro-team@latest, enterprise-server@2.22
const records = await buildRecords(indexName, indexablePages, pageVersion, languageCode)
- const index = process.env.USE_LUNR
+ const index = process.env.AIRGAP
? new LunrIndex(indexName, records)
: new AlgoliaIndex(indexName, records)
@@ -80,7 +80,7 @@ module.exports = async function syncSearchIndexes (opts = {}) {
fs.writeFileSync(cacheFile, JSON.stringify(index, null, 2))
console.log('wrote dry-run index to disk: ', cacheFile)
} else {
- if (process.env.USE_LUNR) {
+ if (process.env.AIRGAP) {
await index.write()
console.log('wrote index to file: ', indexName)
} else {
@@ -93,7 +93,7 @@ module.exports = async function syncSearchIndexes (opts = {}) {
// Fetch a list of index names and cache it for tests
// to ensure that an index exists for every language and GHE version
- const remoteIndexNames = process.env.USE_LUNR
+ const remoteIndexNames = process.env.AIRGAP
? await getLunrIndexNames()
: await getRemoteIndexNames()
const cachedIndexNamesFile = path.join(__dirname, './cached-index-names.json')
diff --git a/middleware/context.js b/middleware/context.js
index 30480c012d35..a2508138aacd 100644
--- a/middleware/context.js
+++ b/middleware/context.js
@@ -24,6 +24,7 @@ module.exports = async function contextualize (req, res, next) {
featureFlags.forEach(featureFlagName => {
req.context.process.env[featureFlagName] = process.env[featureFlagName]
})
+ if (process.env.AIRGAP) req.context.process.env.AIRGAP = true
// define each context property explicitly for code-search friendliness
// e.g. searches for "req.context.page" will include results from this file
@@ -48,11 +49,16 @@ module.exports = async function contextualize (req, res, next) {
// JS + CSS asset paths
req.context.builtAssets = builtAssets
- // Languages and versions for search
- req.context.searchOptions = JSON.stringify({
- languages: Object.keys(languages),
- versions: searchVersions,
- nonEnterpriseDefaultVersion
+ // Object exposing selected variables to client
+ req.context.expose = JSON.stringify({
+ // Languages and versions for search
+ searchOptions: {
+ languages: Object.keys(languages),
+ versions: searchVersions,
+ nonEnterpriseDefaultVersion
+ },
+ // `|| undefined` won't show at all for production
+ airgap: Boolean(process.env.AIRGAP) || undefined
})
return next()
diff --git a/middleware/search.js b/middleware/search.js
index a532386dd367..58025beef6fe 100644
--- a/middleware/search.js
+++ b/middleware/search.js
@@ -22,7 +22,7 @@ router.get('/', async (req, res) => {
}
try {
- const results = process.env.USE_LUNR
+ const results = process.env.AIRGAP
? await loadLunrResults({ version, language, query, limit })
: await loadAlgoliaResults({ version, language, query, limit })
return res.status(200).json(results)