Skip to content

Allow excluding paths when using Netlify Edge FunctionsΒ #10584

Open
@hrishikesh-k

Description

@hrishikesh-k

Describe the problem

I apologize if this functionality already exists. I tried sourcing the docs multiple times, but couldn't find it.

Currently, if one tries to use the Netlify adapter in Edge Functions mode, there's no (easy) way to bypass that. This would be required in the following scenario:

Netlify runs Edge Functions on Deno. Thus, there's no way right now to import node_modules in SvelteKit's API handlers if we wish to use Edge Functions. When using Edge Functions natively, Netlify allow using CDN imports for modules from npm, but as I understand, we can't do that right now using SvelteKit. Thus, users would have to either rely on Netlify Functions for SSR or not use node_modules. Instead, it's possible to use SvelteKit for SSR and write Netlify Functions separately that would use node_modules. But in Edge Function mode, SvelteKit generates an Edge Function for /*, making it impossible to pass the request to Netlify Functions (as Edge Functions run on /.netlify/functions path too).

This would also allow cutting down on Edge Function costs. Instead of running them on every request and ending that with a 404, instead it would be possible to exclude the paths that we know would 404 and save Edge Function invocations. For example, some websites keep getting requests from bots trying to access from wp_assets paths (likely WordPress paths), running Edge Functions for those is a waste of cost when we can have a static 404.html instead.

Since Netlify Redirects kick in after Edge Functions (only if Edge Functions don't return a response), they would not help here.

This is not just limited to using Node Modules, but having SvelteKit take-over all the paths also prevents us from using Netlify's Background Functions, On Demand Builders, Scheduled Functions, Identity's event-triggered functions, etc.

Describe the proposed solution

The proposed solutions would be one or more of the following (sorted by most to least ideal):

  1. Allow excluding paths in kit.adapter.edge settings. Those paths can be passed to Netlify: https://docs.netlify.com/edge-functions/declarations/ and Edge Functions won't execute on those paths at all, allowing users to directly handle whatever happens on those paths.
  2. In /src/hooks.server.ts, allow something like Netlify Edge Function's context.next() to pass the request back to Netlify. This would still be costing Edge Functions invocations, so it's not highly preferred.

Alternatives considered

Tried the following:

  1. Added the following to netlify.toml:
[[edge_functions]]
  function = "render"
  excludedPath = [
    "/.netlify/functions/*"
  ]
  path = "/*"

But, it doesn't work. It generates an Edge Function manifest like:

{
  "routes": [
    {
      "function": "render",
      "pattern": "^/.*$",
      "excluded_patterns": []
    },
    {
      "function": "render",
      "pattern": "^/.*/?$",
      "excluded_patterns": [
        "^/\\.netlify/functions/.*/?$"
      ]
    }
  ],
}

so, SvelteKit's Edge Function is still hit before the custom declaration and it ends up throwing a 404.

  1. Thought of creating my own Edge Function to bypass SvelteKit's, but I'm not sure if that's possible.
  2. Using /src/hooks.server.ts to send a Response.redirect() for the required paths, but that would cause a redirect which is not the desired behaviour.
  3. I was able to work-around this by creating a Netlify Build plugin with the following example code:
import {cwd} from 'node:process'
import {join} from 'node:path'
import {readdirSync, readFileSync, writeFileSync} from 'node:fs'
/**
 * @param {import('@netlify/build/types/netlify_plugin_options.d.ts').NetlifyPluginOptions} meta
 */
export function onPostBuild(meta) {
  const manifestPath = join(meta.constants.EDGE_FUNCTIONS_DIST, 'manifest.json')
  const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'))
  manifest.routes.find(route => {
    return route.function === 'render'
  }).excluded_patterns.push('/.netlify/functions/api/*')
  writeFileSync(manifestPath, JSON.stringify(manifest))
}

Currently, this only excludes /.netlify/functions/api/* path, but this can be used to exclude any other path as well.

Importance

would make my life easier

Additional Information

This is my test site that reproduces the 404s: https://hk-svelte-kit-edge.netlify.app/
Here's the repo: https://github.com/Hrishikesh-K/hk-svelte-kit-edge

Try accessing:

https://hk-svelte-kit-edge.netlify.app/api/ (configured using Netlify Rewrites in /static/_redirects)
https://hk-svelte-kit-edge.netlify.app/.netlify/functions/api/ (native Netlify Functions URL)

Both will throw a 404 rendered by SvelteKit.

Here's a deploy with the plugin adding the exlcusion: https://64e337834a5d7e00080fb3dd--hk-svelte-kit-edge.netlify.app/.netlify/functions/api

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions