Skip to content

Commit

Permalink
docs(blog): update astro post (#6422)
Browse files Browse the repository at this point in the history
  • Loading branch information
necatiozmen authored Oct 22, 2024
1 parent b623b46 commit b59a71c
Showing 1 changed file with 214 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ description: We will learn how to set up Astrojs, create a new project, and basi
slug: astro-js-guide
authors: chidume_nnamdi
tags: [react, dev-tools]
image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-06-12-astro-js/social.png
image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-06-12-astro-js/social-2.png
hide_table_of_contents: false
---

**_This article was last updated on February 7, 2024 to reorganize content for clarity and add new Astro V4 features._**
**This article was last updated on October 22, 2024 to include advanced routing techniques, and using with GraphQL**

## Introduction

Expand Down Expand Up @@ -422,6 +422,80 @@ const posts = getPosts();

With data management capabilities, you can fetch and utilize data from external sources or APIs, empowering you to create dynamic and data-driven websites or applications. Whether you need to display blog posts, populate product information, or showcase real-time data, Astro offers a versatile toolkit for managing data within your projects.

### Nested Routes in Astro

In Astro, the routing is based on, but for more complex route handling, you can nest your pages inside of folders. Suppose you have a blog section, your routes can look something like this:

```bash
└── pages
│ ├── blog
│ │ ├── index.astro
│ │ └── [slug].astro
│ └── index.astro
```

Here's how it works:

- `blog/index.astro` maps to `/blog`, which can be the main blog page.
- `blog/[slug].astro` maps to `/blog/:slug` as a file-based dynamic route, with the `:slug` portion being any dynamic value, such as the ID or title of the blog post.

At this setup, you could think of a blog post like this: `/blog/my-first-post`.

### Dynamic Routing with Astro

Astro also supports dynamic routing with URL parameters. As shown above, you have the ability to create dynamic routes with square brackets `[ ]` in your filenames. For example, `[slug].astro` gives you access to blog posts, products, or any other resource dynamically that would need to be fetched based on a URL.

Here is a simple example:

```tsx
---
const { slug } = Astro.params;
const post = await getPostData(slug);
---

<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
```

Below, `Astro.params.slug` retrieves the dynamic part of the URL so that you can render specific content for each post.

### Programmatic Routing

While file-based routing handles most of the use cases, there are sometimes instances when you want more control over how routes are generated. You can use the advantages of programmatic routing when you may want to conditionally redirect users or generate routes dynamically from data—which could be from an API or a database.

Astro proposes to do this with the `injectRoute()` API, but programmatically injecting routes at build time is still an experimental feature.

### Example:

```js
import { injectRoute } from "astro";

injectRoute({
component: '/src/pages/[slug].astro',
params: { slug: 'my-dynamic-post' }
path: '/blog/my-dynamic-post',
});
```

It exposes a method from which you can inject any dynamic route to your app, basically acting on any of your custom logics.

### Overview Routes with Redirection

You can also deal with redirects. Astro does not support redirects out of the box yet, but you could create the support yourself most easily with HTML meta tag in or with JavaScript inside of your components. Here is a simple example with JavaScript that redirects user to another page:

Alternatively,

```tsx
<script>window.location.href = '/new-url';</script>
```

You could add this to any Astro page to do a client-side redirect.

### Why This Matters

Advanced Routing in Astro gives you the ability to route more complex routing scenarios—especially in larger applications that need nesting, dynamic parameters, and even programmatically route in Astro. Scale your app's structure without complicating the overall architecture.

## Why you should use Astro?

The benefits of using Astro are numerous. We will explore some of them in this section.
Expand Down Expand Up @@ -548,6 +622,144 @@ This feature is still limited to only Markdown files. Hopefully, Astro will intr

The Astro Dev Toolbar enhances your development experience by making it possible to inspect your web page and catch accessibility defects in development. The new release of Astro improves the accessibility rules in the Astro Dev Toolbar.

## Fetching Data with GraphQL in Astro

Here is a short tutorial on how to integrate Astro with GraphQL. GraphQL is pretty useful for fetching structured data from web services. It works seamlessly with Astro in creating dynamic and content-driven websites.

Since Astro doesn't get in the way of using standard JavaScript to fetch data, integrating GraphQL is fairly uneventful. We can leverage any GraphQL client—most notably, `apollo-client`, `graphql-request`, or even just vanilla `fetch`—to create requests and pull data in.

But here's a very basic example with the `graphql-request` library, which is a reasonably lightweight way of fetching data from a GraphQL API.

### Install `graphql-request`

First, install the `graphql-request` package:

```bash
npm install graphql-request
```

### GraphQL API Data Fetching

So far in your Astro component, you can fetch data from a GraphQL endpoint. Following is an example of fetching posts from an imaginary GraphQL API:

```tsx
---
import { request, gql } from 'graphql-request';

const query = gql`
query {
posts {
title
content
slug
}
}
`;

const { posts } = await request('https://example.com/graphql', query);
---

<article>
{posts.map((post) => (
<div key={post.slug}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</div>
))}
</article>
```

In this example:

- The `gql` template literal is used to define the GraphQL query.
- `request()` retrieves the data from the GraphQL API.
- The data is then dynamically rendered inside the component.

### Step 3: Handling Dynamic Queries

You can also make dynamic GraphQL queries based on parameters, like for example, a blog post slug. For example, to fetch a post having a specific URL slug:

```tsx

import { request, gql } from "graphql-request";

const { slug } = Astro.params;

const query = gql`
query ($slug: String!) {
post(slug: $slug) {
title
content
}
}
`;

const { post } = await request('https://example.com/graphql', query, {
slug
});


<article>
<h1>{post.title}</h1>
<p>{post.content}
</article>
```

What we are doing here is passing the slug parameter in from the URL into the GraphQL query, so it fetches the right content dynamically.

### Why Use GraphQL with Astro?

- **Efficient Data Fetching**: GraphQL fetches only the needed data to make the payload size and performance better.
- **Flexible Queries**: Given your requirement, you can exactly ask for what you need in one query without over-fetching or under-fetching your data.
- **Unified Data Source**: You could fetch data from multiple sources with one GraphQL API, thus making it easier to manage content from several locations.

### Tools for Simplifying GraphQL in Astro

You can also use more advanced GraphQL clients like `Apollo Client` for more complex needs—for example caching or subscriptions. Here is how you could set up `Apollo Client` in Astro:

1. **Apollo Client Installation**:

```bash
npm install @apollo/client graphql
```

2. **Apollo Provider Setup**:
Now, we need to create an `apollo.js` file for configuring the Apollo Client:

```js
import { ApolloClient, InMemoryCache } from "@apollo/client";

const client = new ApolloClient({
uri: "https://example.com/graphql",
cache: new InMemoryCache(),
});

export default client;
```

3. **Using Apollo in Components**:
It means you can now make use of the `useQuery` hook from Apollo in the components:

```tsx
const { loading, error, data } = useQuery(GET_POSTS);

if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;

return (
<div>
{data.posts.map((post) => (
<div key={post.title}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</div>
))}
</div>
);
```

This will provide the groundwork for a more feature-filled integration, such as caching and support for multiple GraphQL queries within your Astro project.

## Conclusion

Astro is a popular front-end framework. You can use it to build performant, content-rich websites such as blogs, landing pages, documentation sites, and portfolios.
Expand Down

0 comments on commit b59a71c

Please sign in to comment.