skip to Main Content

I have a TypeScript library that, under given conditions, should redirect to an error page.
One way would be using the internal Astro global object, like with Astro.redirect('/404'). Unfortunately, Astro seems not accessible when rendering MDX pages.

Here is a MWE, where, for simplicity, I am using Astro.url.

foo.mdx:

---
layout: ./foolayout.astro
---

hello

foolayout.astro:

---
import {url} from "./foolib.ts";
---
{url}
<slot />

foolib.ts:

export const url = Astro.url; 

This gives the error: Astro is not defined.

Note that, if I use the Astro global object in the layout file, I have no errors. That is:
foolayout.astro:

---
---
{Astro.url}
<slot />

However, I need to use it from the TypeScript library, when a given condition is met.

EDIT – Astro.redirect

This edit is to clarify my actual use case, involving Astro.redirect().

The library would be like so:

foolib.ts:

export function redir(): void {
   // Check some condition and possibly...
   return Astro.redirect('/404')
} 

Thus, the layout would be:

foolayout.astro:

---
import { redir } from "./foolib.ts";
redir();
---
<slot />

This again raises the Astro’s not defined error.

In this case, if attempting to use Astro global from the layout frontmatter:

foolayout.astro:

---
// Check some condition and possibly...
return Astro.redirect('/404');
---
<slot />

We get, in the Astro console, an undefined.

We can replace the MDX with an .astro file.

foo2.astro:

---
import Layout from "./foolayout.astro";
---
<Layout>
hello
</Layout>

With the first layout, importing foolib, we get the same error; with the second, using Astro global in the frontmatter, we get a more descriptive error:

ResponseSentError
Unable to set response.
The response has already been sent to the browser and cannot be altered.

This suggests that Astro global might be accessed from an Astro component, as also noted in this Reddit post.

2

Answers


  1. Chosen as BEST ANSWER

    I haven't found a proper way to access the global Astro, but this is a workaround specific for the redirect case.

    The redirect case is challenging because Astro components run on the server, so one can’t access document window or others browser-specific objects during rendering.

    Below, the .ts library returns an error condition and a script is conditionally run when it is true.

    foolib.ts

    // Some code possibly returning an error condition 
    const errCond: boolean = true;
    
    export function raiseErr(): boolean {
        return errCond;
    }
    

    foolayout.astro

    ---
    import { raiseErr } from "./foolib.ts";
    ---
    
    {raiseErr() ? (
      <script> window.location.pathname = "/404"; </script> ) : null}
    
    <slot />
    

  2. If you want to do a redirect, you need to do that from the frontmatter. Down in the HTML is already too late. Try something like:

    ---
    import lib from "./foolib.ts";
    
    const res = lib.getSomething()
    if (res === undefined) { // or similar condition
       return Astro.redirect('/404')
    }
    ---
    
    <slot />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search