Use proxy routeRules in build hook

I have created a custom Nuxt module that sends data to a cms on build:done hook. The cms location is configured in routeRules with proxy enabled. So far I have tried $fetch or useFetch but both are not available in this context ofcourse. How could I use the proxy rewrite in a build hook?
6 Replies
kapa.ai
kapa.ai2w ago
Hi @snakemastr508. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To use proxy routeRules in a build hook, you'll need a different approach since $fetch and useFetch are not available in the build hook context. These composables are designed to work within the Nuxt application context, not during the build process. Based on the knowledge sources, here are some approaches you could take: Using Native fetch or Node.js HTTP Clients In your build hook, you can use native fetch (if available in your Node.js version) or other HTTP clients like node-fetch, axios, or got to make the request directly to your CMS, bypassing the proxy configuration.
import { defineNuxtModule } from '@nuxt/kit'
import fetch from 'node-fetch' // or another HTTP client

export default defineNuxtModule({
setup(options, nuxt) {
nuxt.hook('build:done', async () => {
// Direct request to CMS without using the proxy
const response = await fetch('<https://your-cms-url.com/api/endpoint',> {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ data: 'your data' }),
})

const result = await response.json()
console.log('Data sent to CMS:', result)
})
}
})
import { defineNuxtModule } from '@nuxt/kit'
import fetch from 'node-fetch' // or another HTTP client

export default defineNuxtModule({
setup(options, nuxt) {
nuxt.hook('build:done', async () => {
// Direct request to CMS without using the proxy
const response = await fetch('<https://your-cms-url.com/api/endpoint',> {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ data: 'your data' }),
})

const result = await response.json()
console.log('Data sent to CMS:', result)
})
}
})
Accessing Proxy Configuration If you need to use the same proxy configuration defined in your routeRules, you can access the Nitro configuration to get the proxy details:
import { defineNuxtModule } from '@nuxt/kit'
import fetch from 'node-fetch'
export default defineNuxtModule({
setup(options, nuxt) {
nuxt.hook('build:done', async () => {
// Access the routeRules configuration
const routeRules = nuxt.options.nitro?.routeRules || {}

// Find your proxy configuration
const cmsProxyRule = routeRules['/your-proxy-path']

if (cmsProxyRule?.proxy) {
// Extract the target URL from the proxy configuration
const targetUrl = typeof cmsProxyRule.proxy === 'string'
? cmsProxyRule.proxy
: cmsProxyRule.proxy.to

// Make the request directly to the target URL
const response = await fetch(`${targetUrl}/endpoint`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ data: 'your data' }),
})

const result = await response.json()
console.log('Data sent to CMS:', result)
}
})
}
})
import { defineNuxtModule } from '@nuxt/kit'
import fetch from 'node-fetch'
export default defineNuxtModule({
setup(options, nuxt) {
nuxt.hook('build:done', async () => {
// Access the routeRules configuration
const routeRules = nuxt.options.nitro?.routeRules || {}

// Find your proxy configuration
const cmsProxyRule = routeRules['/your-proxy-path']

if (cmsProxyRule?.proxy) {
// Extract the target URL from the proxy configuration
const targetUrl = typeof cmsProxyRule.proxy === 'string'
? cmsProxyRule.proxy
: cmsProxyRule.proxy.to

// Make the request directly to the target URL
const response = await fetch(`${targetUrl}/endpoint`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ data: 'your data' }),
})

const result = await response.json()
console.log('Data sent to CMS:', result)
}
})
}
})
Using the Nitro Hook System Another approach is to use Nitro hooks to execute your code after the server is ready:
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
setup(options, nuxt) {
// Configure Nitro hooks
nuxt.hook('nitro:config', (nitroConfig) => {
nitroConfig.hooks = nitroConfig.hooks || {}
nitroConfig.hooks.ready = nitroConfig.hooks.ready || []

// Add a hook that runs when Nitro server is ready
nitroConfig.hooks.ready.push(async (nitro) => {
// Here you can make your request to the CMS
// You'll need to use a Node.js HTTP client here
})
})
}
})
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
setup(options, nuxt) {
// Configure Nitro hooks
nuxt.hook('nitro:config', (nitroConfig) => {
nitroConfig.hooks = nitroConfig.hooks || {}
nitroConfig.hooks.ready = nitroConfig.hooks.ready || []

// Add a hook that runs when Nitro server is ready
nitroConfig.hooks.ready.push(async (nitro) => {
// Here you can make your request to the CMS
// You'll need to use a Node.js HTTP client here
})
})
}
})
The proxy routeRules are primarily designed for runtime request handling rather than build-time operations. For build hooks, it's generally more straightforward to make direct HTTP requests to your CMS endpoint. For more information on Nuxt modules and hooks, you can refer to the Nuxt Module Author Guide. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@592989808046112779> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
snakemastr508
snakemastr508OP7d ago
@kapa.ai And how would the second option look like if my proxy rule is dynamic and has authentication headers like routeRules: { '/cms/**': { proxy: { to: 'http://localhost:3000/api/**', headers: { Authorization: 'Basic {insert_key_here}' } } } }
kapa.ai
kapa.ai7d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I'll show you how to access and use a dynamic proxy rule with authentication headers in your build hook. Here's how you can modify the second approach to handle this scenario:
import { defineNuxtModule } from '@nuxt/kit'
import fetch from 'node-fetch'

export default defineNuxtModule({
setup(options, nuxt) {
nuxt.hook('build:done', async () => {
// Access the routeRules configuration
const routeRules = nuxt.options.nitro?.routeRules || {}

// Find your proxy configuration for '/cms/**'
const cmsProxyRule = routeRules['/cms/**']

if (cmsProxyRule?.proxy) {
// Extract the target URL and headers from the proxy configuration
const proxyConfig = typeof cmsProxyRule.proxy === 'string'
? { to: cmsProxyRule.proxy, headers: {} }
: cmsProxyRule.proxy

const targetUrl = proxyConfig.to
const authHeaders = proxyConfig.headers || {}

// Replace the wildcard pattern in the URL if needed
// For example, if you're sending to '/cms/posts', the target would be '<http://localhost:3000/api/posts'>
const endpoint = '/your-specific-endpoint' // The specific endpoint you want to hit
const targetEndpoint = targetUrl.replace('/**', endpoint)

// Make the request directly to the target URL with the auth headers
const response = await fetch(targetEndpoint, {
method: 'POST', // or whatever method you need
headers: {
'Content-Type': 'application/json',
...authHeaders // This will include your Authorization header
},
body: JSON.stringify({ data: 'your data' }),
})

const result = await response.json()
console.log('Data sent to CMS:', result)
}
})
}
})
import { defineNuxtModule } from '@nuxt/kit'
import fetch from 'node-fetch'

export default defineNuxtModule({
setup(options, nuxt) {
nuxt.hook('build:done', async () => {
// Access the routeRules configuration
const routeRules = nuxt.options.nitro?.routeRules || {}

// Find your proxy configuration for '/cms/**'
const cmsProxyRule = routeRules['/cms/**']

if (cmsProxyRule?.proxy) {
// Extract the target URL and headers from the proxy configuration
const proxyConfig = typeof cmsProxyRule.proxy === 'string'
? { to: cmsProxyRule.proxy, headers: {} }
: cmsProxyRule.proxy

const targetUrl = proxyConfig.to
const authHeaders = proxyConfig.headers || {}

// Replace the wildcard pattern in the URL if needed
// For example, if you're sending to '/cms/posts', the target would be '<http://localhost:3000/api/posts'>
const endpoint = '/your-specific-endpoint' // The specific endpoint you want to hit
const targetEndpoint = targetUrl.replace('/**', endpoint)

// Make the request directly to the target URL with the auth headers
const response = await fetch(targetEndpoint, {
method: 'POST', // or whatever method you need
headers: {
'Content-Type': 'application/json',
...authHeaders // This will include your Authorization header
},
body: JSON.stringify({ data: 'your data' }),
})

const result = await response.json()
console.log('Data sent to CMS:', result)
}
})
}
})
This approach: 1. Accesses your dynamic proxy rule configuration from nuxt.options.nitro.routeRules 2. Extracts both the target URL and the authentication headers 3. Preserves the authentication headers when making the request 4. Handles the wildcard pattern replacement if needed If you need to make requests to multiple endpoints that match your wildcard pattern, you can create a helper function:
function createCmsRequest(targetUrl, authHeaders) {
return async (endpoint, data, method = 'POST') => {
// Replace wildcards in the URL pattern
const targetEndpoint = targetUrl.replace('/**', endpoint)

const response = await fetch(targetEndpoint, {
method,
headers: {
'Content-Type': 'application/json',
...authHeaders
},
body: JSON.stringify(data),
})

return response.json()
}
}

// Then in your hook:
const makeRequest = createCmsRequest(targetUrl, authHeaders)
const result = await makeRequest('/posts', { title: 'New Post' })
function createCmsRequest(targetUrl, authHeaders) {
return async (endpoint, data, method = 'POST') => {
// Replace wildcards in the URL pattern
const targetEndpoint = targetUrl.replace('/**', endpoint)

const response = await fetch(targetEndpoint, {
method,
headers: {
'Content-Type': 'application/json',
...authHeaders
},
body: JSON.stringify(data),
})

return response.json()
}
}

// Then in your hook:
const makeRequest = createCmsRequest(targetUrl, authHeaders)
const result = await makeRequest('/posts', { title: 'New Post' })
This approach gives you a reusable way to make authenticated requests to your CMS during the build process while leveraging the same configuration you've defined in your routeRules. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai7d ago
<@592989808046112779> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
snakemastr508
snakemastr508OP7d ago
Thank you!

Did you find this page helpful?