Reputation: 417
I have JSON files which contain the data for my posts that are in src/data/posts/
. I'm trying to create pages for each of those posts. This is my structure:
[projects]
|---[project].svelte
|---index.svelte
index.svelte
contains code that lists all my posts. In [project].svelte
, I would like to render the content of the relevant post. I have tried this:
<script context="module">
// All posts are contained in src/data/posts
// First, read the page.params.project and find the matching
// file name and read the data from that file.
export async function load({ page, fetch }) {
const slug = page.params.project;
let post;
const url = `/src/data/posts/${slug}.json`
post = await fetch(url)
console.log(post)
}
</script>
However, this is not getting my JSON file. I get the following response:
500
Unexpected token < in JSON at position 0
SyntaxError: Unexpected token < in JSON at position 0
I console logged the response and it was this:
[0] Response {
[0] size: 0,
[0] [Symbol(Body internals)]: {
[0] body: <Buffer 3c 21 44 4f 43 54 59 50 45 20 68 74 6d 6c 3e 0a 3c 68 74 6d 6c 20 6c 61 6e 67 3d 22 65 6e 22 3e 0a 20 20 3c 68 65 61 64 3e 0a 20 20 20 20 0a 0a 09 09 ... 59964 more bytes>,
[0] boundary: null,
[0] disturbed: false,
[0] error: null
[0] },
[0] [Symbol(Response internals)]: {
[0] type: 'default',
[0] url: undefined,
[0] status: 404,
[0] statusText: '',
[0] headers: {
[0] 'content-type': 'text/html',
[0] 'permissions-policy': 'interest-cohort=()'
[0] },
[0] counter: undefined,
[0] highWaterMark: undefined
[0] }
[0] }
Can I not use fetch this way? How else do I do this? What would be the proper way to get my post?
Upvotes: 1
Views: 3476
Reputation: 121
The path to the file I was trying to fetch: src/routes/posts/index.json.ts
What I had before (which was giving me an error):
500 Unexpected token < in JSON at position 0 SyntaxError: Unexpected token < in JSON at position 0
<script context="module" lang="ts">
import type { Load } from "@sveltejs/kit";
export const load: Load = async ({ fetch, url }) => {
const res = await fetch("../routes/posts/index.json");
return { props: { posts: await res.json() } };
};
</script>
What I had after (fixed):
<script context="module" lang="ts">
import type { Load } from "@sveltejs/kit";
export const load: Load = async ({ fetch, url }) => {
const res = await fetch("/posts.json");
return { props: { posts: await res.json() } };
};
</script>
I ended up solving this after reading the updated Sveltekit docs here
Upvotes: 0
Reputation: 417
Since fetch only works for external servers, I used dynamic imports to solve this problem. The same code is now written as:
<script context="module">
export async function load({ page }) {
try {
const Post = await import(`../../data/posts/${page.params.project}.json`);
console.log(Post);
return {
// Data passed into svelte component
props: {
Post:Post.default
}
};
} catch (e) {
return {
props: {
Post: {
headling: "404",
content: "Page not found"
}
}
};
}
}
</script>
And I can make Posts
available like so:
<script>
export let Post;
</script>
This gives me access to the JSON key-value pairs (like Post.title
).
Upvotes: 1
Reputation: 1811
You need to convert your fetch response
into JSON
.
this can be done using .json()
<script context="module">
// All posts are contained in src/data/posts
// First, read the page.params.project and find the matching
// file name and read the data from that file.
export async function load({ page, fetch }) {
const slug = page.params.project;
let post;
const url = `/src/data/posts/${slug}.json`
const resp = await fetch(url) /* added this line */
post = await resp.json() /* added this line */
console.log(post)
}
</script>
Upvotes: 1