Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions nuxt/composables/useBlogList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ export const BLOG_PAGE_SIZE = 19
// which of these show as nav buttons; 'tips' has a route but isn't in that button list).
export const BLOG_TAGS = ['how-to', 'node-red', 'ai', 'uns', 'dashboard', 'flowfuse', 'releases', 'news', 'plc', 'mqtt', 'opcua', 'modbus', 'tips']

// Mirrors .eleventy.js's DEV_MODE_POSTS: future-dated posts are hidden outside production
// (Netlify sets CONTEXT), so deploy previews and dev can still preview scheduled posts.
// Mirrors .eleventy.js's DEV_MODE_POSTS: future-dated posts are hidden outside production,
// so deploy previews and dev can still preview scheduled posts. The flag is baked at build
// time (see nuxt.config.ts) rather than read from process.env here: a scheduled post gets no
// prerendered file, so its URL is served by the Netlify function, where process.env.CONTEXT
// is always undefined. That switched this check off and served the post before its date.
export function isFuturePost(date: string | Date): boolean {
return new Date(date) > new Date() && process.env.CONTEXT === 'production'
return new Date(date) > new Date() && useRuntimeConfig().public.isProductionContext
}

export function useBlogList(tag: string | null, pageNumber: number) {
Expand Down
11 changes: 7 additions & 4 deletions nuxt/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,14 @@ export default defineNuxtConfig({
devtools: { enabled: true },
modules: ['@nuxt/ui', '@nuxt/content', '@nuxtjs/seo', 'nuxt-studio', '@nuxt/image', './modules/docs-source', 'nuxt-llms'],

// Captured at build time (Netlify sets CONTEXT during the build, not necessarily
// in the deployed Function's runtime), then baked into the server bundle via
// runtimeConfig so analytics.ts doesn't depend on a process.env read at request time.
// Captured at build time (Netlify sets CONTEXT during the build, but passes only URL,
// SITE_NAME and SITE_ID to the deployed Function at runtime), then baked in via
// runtimeConfig so nothing depends on a process.env read at request time. Under `public`
// so the blog's scheduled-post check reads the same value everywhere it runs.
runtimeConfig: {
isProductionContext: process.env.CONTEXT === 'production'
public: {
isProductionContext: process.env.CONTEXT === 'production'
}
},

css: ['~/assets/css/theme.css'],
Expand Down
2 changes: 1 addition & 1 deletion nuxt/server/plugins/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ let headHtml: string | null = null
let bodyHtml: string | null = null

export default defineNitroPlugin((nitroApp) => {
if (import.meta.dev || !useRuntimeConfig().isProductionContext) return
if (import.meta.dev || !useRuntimeConfig().public.isProductionContext) return

nitroApp.hooks.hook('render:html', async (html) => {
if (html.bodyAppend.some(s => s.includes('cc.min.js'))) return
Expand Down
9 changes: 6 additions & 3 deletions nuxt/server/routes/blog/index.xml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ function escapeXml(value: string): string {
.replace(/>/g, '>')
}

function isFuturePost(date: string | Date): boolean {
return new Date(date) > new Date() && process.env.CONTEXT === 'production'
// See useBlogList.ts: the production flag is baked at build time, not read from
// process.env, which is empty of it inside the deployed Netlify function.
function isFuturePost(date: string | Date, isProductionContext: boolean): boolean {
return new Date(date) > new Date() && isProductionContext
}

// entry.body is a minimark tree: { value: MinimarkNode[] } where a node is
Expand Down Expand Up @@ -178,7 +180,8 @@ export default defineEventHandler(async (event) => {
const people = { ...teamPeople, ...guestPeople }
// Full post bodies are heavy - cap the feed to the most recent posts rather
// than shipping the entire multi-megabyte blog archive on every request.
const entries = allEntries.filter(entry => !isFuturePost(entry.date)).slice(0, 20)
const { isProductionContext } = useRuntimeConfig(event).public
const entries = allEntries.filter(entry => !isFuturePost(entry.date, isProductionContext)).slice(0, 20)

// Mirrors useReleaseFeaturePage: splices plan-availability badges and changelog/docs
// links into a release blog's body, resolved from its `features:` frontmatter.
Expand Down