N
Nuxt3mo ago
Dog

[closed] Page appearing empty when navigating (but not directly)

On my website, https://nuxt.whitecoastrailway.com, clicking on News and Jobs in the navigation return pages with no actual content, only the header and footer (which itself is covered by the header). I'm using Sanity with the official module as my CMS to display news posts and job listings, and almost the same code is used is used on each index page. Here's the script in the jobs page: (bit messy but idc)
import type { SanityDocument } from "@sanity/client";
const router = useRouter();

const JOBS_QUERY = groq`*[
_type == "job"
&& defined(slug.current)
]|order(title, description)[0...12]{_id, title, description, department, open, slug}`;

const { data: jobs } = await useSanityQuery<SanityDocument[]>(JOBS_QUERY);

const results = ref<SanityDocument[] | null>(jobs.value ?? null);
const search = ref(decodeURIComponent(useRoute().query.search as string || ''));

watch(search, () => {
if (search.value) {
router.push({ query: { search: search.value } });
} else {
router.push({ query: {} });
}
});

const handleSearch = () => {
results.value = jobs.value?.filter((job) =>
Object.values(job).some((value) => value.toString().toLowerCase().includes(search.value.toLowerCase()))
) || [];
};
import type { SanityDocument } from "@sanity/client";
const router = useRouter();

const JOBS_QUERY = groq`*[
_type == "job"
&& defined(slug.current)
]|order(title, description)[0...12]{_id, title, description, department, open, slug}`;

const { data: jobs } = await useSanityQuery<SanityDocument[]>(JOBS_QUERY);

const results = ref<SanityDocument[] | null>(jobs.value ?? null);
const search = ref(decodeURIComponent(useRoute().query.search as string || ''));

watch(search, () => {
if (search.value) {
router.push({ query: { search: search.value } });
} else {
router.push({ query: {} });
}
});

const handleSearch = () => {
results.value = jobs.value?.filter((job) =>
Object.values(job).some((value) => value.toString().toLowerCase().includes(search.value.toLowerCase()))
) || [];
};
14 Replies
kapa.ai
kapa.ai3mo ago
Hi @Dog. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided in the knowledge sources and your question, it appears that you're experiencing an issue with page content not appearing when navigating between pages on your Nuxt website. This problem is likely related to the way your pages are being rendered and how the content is fetched. The issue you're describing is similar to a problem discussed in this Stack Overflow post. In that case, the useFetch composable wasn't working reactively when navigating to a route using nuxt-link. To address this issue, you might want to consider the following approaches: 1. Ensure that your content fetching is reactive: Make sure that your Sanity query is reactive to route changes. You can do this by using the useAsyncData composable along with the current route path. Here's an example of how you might modify your code:
const route = useRoute()
const { data: jobs } = await useAsyncData(route.path, () => {
return useSanityQuery<SanityDocument[]>(JOBS_QUERY)
})

const route = useRoute()
const { data: jobs } = await useAsyncData(route.path, () => {
return useSanityQuery<SanityDocument[]>(JOBS_QUERY)
})

This approach is similar to the one suggested in the Nuxt Content documentation for implementing document-driven mode. 2. Check your layout and page transitions: Sometimes, issues with content not appearing can be related to layout or transition problems. Make sure your layout is properly set up and that any page transitions are not interfering with content rendering. 3. Verify that your Sanity query is working as expected: Double-check that your Sanity query is returning the expected results. You might want to add some error handling or logging to ensure that the data is being fetched correctly. 4. Consider using Nuxt Content: If you're open to alternatives, you might want to consider using Nuxt Content for managing your content. It provides a file-based CMS that integrates well with Nuxt and might be easier to debug. If these suggestions don't resolve your issue, you may need to provide more details about your setup, including your nuxt.config.ts file and the full code for your pages. Additionally, checking the browser console for any errors could provide more insight into what's happening during navigation. Remember that without seeing your full codebase and configuration, it's challenging to pinpoint the exact cause of the issue. If the problem persists, you might want to create a minimal reproducible example and seek further assistance on the Nuxt GitHub issues page or the Nuxt Discord community. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@634054240557596672> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Dog
DogOP3mo ago
@kapa.ai done that but how do i fix Property 'filter' does not exist on type '_AsyncData<SanityDocument[] | null, Error>' here:
const handleSearch = () => {
results.value = jobs?.value?.filter((job: SanityDocument) =>
Object.values(job).some((value) => value.toString().toLowerCase().includes(search.value.toLowerCase()))
) || [];
};
const handleSearch = () => {
results.value = jobs?.value?.filter((job: SanityDocument) =>
Object.values(job).some((value) => value.toString().toLowerCase().includes(search.value.toLowerCase()))
) || [];
};
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the error message you're encountering, it seems that the jobs variable is of type _AsyncData<SanityDocument[] | null, Error>, which doesn't have a filter method directly available. This is likely because useAsyncData returns a wrapped version of your data. To fix this issue, you need to access the actual array of SanityDocument objects. Here's how you can modify your handleSearch function to work with the _AsyncData type:
const handleSearch = () => {
if (jobs.data && Array.isArray(jobs.data.value)) {
results.value = jobs.data.value.filter((job: SanityDocument) =>
Object.values(job).some((value) =>
value.toString().toLowerCase().includes(search.value.toLowerCase())
)
);
} else {
results.value = [];
}
};
const handleSearch = () => {
if (jobs.data && Array.isArray(jobs.data.value)) {
results.value = jobs.data.value.filter((job: SanityDocument) =>
Object.values(job).some((value) =>
value.toString().toLowerCase().includes(search.value.toLowerCase())
)
);
} else {
results.value = [];
}
};
This approach addresses the issue by: 1. Checking if jobs.data exists and is an array using Array.isArray(). 2. Applying the filter on jobs.data.value instead of jobs?.value. 3. Setting results.value to an empty array if the data is not available or not in the expected format. The reason for this change is that when using useAsyncData, the data is wrapped in a structure that includes additional properties like data, pending, and error. The actual data you want to filter is located in the data.value property of this structure. For more information on how useAsyncData works and its return type, you can refer to the Nuxt documentation on useAsyncData. Remember to adjust your type annotations accordingly. If you're using TypeScript, you might want to explicitly type your jobs variable:
const { data: jobs } = await useAsyncData<SanityDocument[] | null>('jobs', () =>
useSanityQuery<SanityDocument[]>(JOBS_QUERY)
);
const { data: jobs } = await useAsyncData<SanityDocument[] | null>('jobs', () =>
useSanityQuery<SanityDocument[]>(JOBS_QUERY)
);
This will help TypeScript understand the structure of your data and provide better type checking. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@634054240557596672> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Dog
DogOP3mo ago
@kapa.ai jobs.data does not exist, that's not how useAsyncData works
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I apologize for the confusion in my previous response. You are correct, and I made a mistake in explaining how useAsyncData works. Let me provide you with the correct information based on the Nuxt documentation. According to the Nuxt documentation on useAsyncData, useAsyncData returns an object with a data property, which is a ref containing the result of the asynchronous function. To correctly handle the search functionality with the data returned by useAsyncData, you should modify your handleSearch function like this:
const handleSearch = () => {
if (jobs.value && Array.isArray(jobs.value)) {
results.value = jobs.value.filter((job: SanityDocument) =>
Object.values(job).some((value) =>
value.toString().toLowerCase().includes(search.value.toLowerCase())
)
);
} else {
results.value = [];
}
};
const handleSearch = () => {
if (jobs.value && Array.isArray(jobs.value)) {
results.value = jobs.value.filter((job: SanityDocument) =>
Object.values(job).some((value) =>
value.toString().toLowerCase().includes(search.value.toLowerCase())
)
);
} else {
results.value = [];
}
};
In this corrected version: 1. We check if jobs.value exists and is an array. 2. We apply the filter directly on jobs.value, which contains the array of SanityDocument objects. 3. If jobs.value is not available or not an array, we set results.value to an empty array. This approach aligns with how useAsyncData actually works in Nuxt. The data property returned by useAsyncData is already a ref, so you access its value using .value. Thank you for pointing out the error, and I apologize again for any confusion my previous response may have caused. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@634054240557596672> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Dog
DogOP3mo ago
const { data: jobs, error } = await useAsyncData(JOBS_QUERY, () => useSanityQuery<SanityDocument[]>(JOBS_QUERY));

if (error.value) {
throw createError({
statusCode: 500,
statusMessage: `Failed to fetch jobs`,
})
}
const { data: jobs, error } = await useAsyncData(JOBS_QUERY, () => useSanityQuery<SanityDocument[]>(JOBS_QUERY));

if (error.value) {
throw createError({
statusCode: 500,
statusMessage: `Failed to fetch jobs`,
})
}
gives the error [nuxt] [request error] [unhandled] [500] Cannot stringify a function @kapa.ai
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the error message you're encountering, it appears that you're facing an issue related to data serialization when using useAsyncData with useSanityQuery. This error typically occurs when trying to serialize data that contains functions or other non-serializable content. The error "Cannot stringify a function" is often associated with the devalue library, which Nuxt uses for serialization. This is mentioned in the Nuxt documentation on data fetching: "When using useAsyncData and useLazyAsyncData to transfer data fetched on server to the client (as well as anything else that utilizes the Nuxt payload), the payload is serialized with devalue." To address this issue, you can try the following approaches: 1. Ensure that your JOBS_QUERY doesn't include any functions or non-serializable content. Double-check your Sanity query to make sure it only returns serializable data. 2. If the issue persists, you can try using a custom serializer. The Nuxt documentation provides an example of using a custom serializer with superjson:
import superjson from 'superjson'

const { data: jobs, error } = await useAsyncData(JOBS_QUERY, async () => {
const result = await useSanityQuery<SanityDocument[]>(JOBS_QUERY)
return superjson.stringify(result) as unknown as SanityDocument[]
}, {
transform: (value) => {
return superjson.parse(value as unknown as string)
},
})

import superjson from 'superjson'

const { data: jobs, error } = await useAsyncData(JOBS_QUERY, async () => {
const result = await useSanityQuery<SanityDocument[]>(JOBS_QUERY)
return superjson.stringify(result) as unknown as SanityDocument[]
}, {
transform: (value) => {
return superjson.parse(value as unknown as string)
},
})

This approach uses superjson to handle the serialization and deserialization of the data, which might resolve the issue with non-serializable content. 3. If the problem is specifically with the Sanity query results, you might need to transform the data before returning it from useSanityQuery. For example:
const { data: jobs, error } = await useAsyncData(JOBS_QUERY, async () => {
const result = await useSanityQuery<SanityDocument[]>(JOBS_QUERY)
return result.map(job => ({
// Include only serializable properties
id: job._id,
title: job.title,
description: job.description,
// ... other serializable properties
}))
})

const { data: jobs, error } = await useAsyncData(JOBS_QUERY, async () => {
const result = await useSanityQuery<SanityDocument[]>(JOBS_QUERY)
return result.map(job => ({
// Include only serializable properties
id: job._id,
title: job.title,
description: job.description,
// ... other serializable properties
}))
})

This ensures that only serializable data is returned from the query. If these approaches don't resolve the issue, you might need to investigate further what specific data in your Sanity query result is causing the serialization problem. You could try logging the result of useSanityQuery before passing it to useAsyncData to see if there are any unexpected function properties or circular references that could be causing the issue. Remember, without seeing the full content of your JOBS_QUERY and the exact structure of the data returned by Sanity, it's challenging to pinpoint the exact cause of the serialization error. If the problem persists, you might want to create a minimal reproducible example and seek further assistance from the Nuxt or Sanity communities. Nuxt Data Fetching Documentation ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@634054240557596672> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Dog
DogOP3mo ago
@kapa.ai
const JOBS_QUERY = groq`*[
_type == "job"
&& defined(slug.current)
]|order(title, description)[0...12]{_id, title, description, department, open, slug}`;
const JOBS_QUERY = groq`*[
_type == "job"
&& defined(slug.current)
]|order(title, description)[0...12]{_id, title, description, department, open, slug}`;
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the GROQ query you've provided, it appears that this is a valid Sanity query for fetching job documents. The query itself doesn't contain any functions or non-serializable content that would directly cause the "Cannot stringify a function" error you encountered earlier. Let's break down the query: 1. It selects all documents of type "job" 2. It filters for jobs that have a defined slug.current 3. It orders the results by title and description 4. It limits the results to the first 12 documents 5. It projects only specific fields: _id, title, description, department, open, and slug This query should return an array of job objects with serializable data. However, the error you're experiencing is likely occurring during the process of fetching or processing this data, rather than in the query itself. To troubleshoot the issue, you could try the following: 1. Use useSanityQuery without useAsyncData first to see if the problem is with the Sanity query or with the useAsyncData wrapper:
const { data: jobs, error } = await useSanityQuery<SanityDocument[]>(JOBS_QUERY);

if (error.value) {
throw createError({
statusCode: 500,
statusMessage: `Failed to fetch jobs`,
});
}

const { data: jobs, error } = await useSanityQuery<SanityDocument[]>(JOBS_QUERY);

if (error.value) {
throw createError({
statusCode: 500,
statusMessage: `Failed to fetch jobs`,
});
}

2. If that works, then try wrapping it with useAsyncData, but without awaiting the result:
const { data: jobs, error } = useAsyncData(JOBS_QUERY, () =>
useSanityQuery<SanityDocument[]>(JOBS_QUERY)
);

const { data: jobs, error } = useAsyncData(JOBS_QUERY, () =>
useSanityQuery<SanityDocument[]>(JOBS_QUERY)
);

3. If you still encounter the error, it might be worth logging the result of the Sanity query before it's processed by useAsyncData:
const { data: jobs, error } = useAsyncData(JOBS_QUERY, async () => {
const result = await useSanityQuery<SanityDocument[]>(JOBS_QUERY);
console.log(JSON.stringify(result, null, 2));
return result;
});

const { data: jobs, error } = useAsyncData(JOBS_QUERY, async () => {
const result = await useSanityQuery<SanityDocument[]>(JOBS_QUERY);
console.log(JSON.stringify(result, null, 2));
return result;
});

This will help you see if there's any unexpected data in the query result that might be causing the serialization issue. If none of these approaches resolve the issue, you might need to investigate further into how the Sanity module is integrated with your Nuxt application. The error could be related to how the Sanity client is initialized or how the data is being processed before it reaches useAsyncData. For more information on using Sanity with Nuxt, you can refer to the official Sanity module for Nuxt documentation. If the problem persists, you might want to reach out to the Sanity community or create an issue on the Nuxt Sanity module GitHub repository for more specific assistance. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@634054240557596672> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?