Xaohs
Xaohs
Explore posts from servers
TTCTheo's Typesafe Cult
Created by Xaohs on 2/21/2024 in #questions
Unsure how to do this pattern in app router
Hey everyone, I'm still getting the hang of using the app router and I've come across something that puzzles me. Suppose I'm retrieving data in a page.tsx file and passing it as props to a component that requires this data. To manage the loading state, I'd typically wrap the component within a <Suspense/> tag. However, it appears <Suspense/> doesn't recognize that the nested component is waiting for data since the data fetching occurs at a higher level in the component tree. Is that correct? It seems like the solution is to move data fetching inside the component itself. However, if I need to render something that specifically requires client-side execution, it would necessitate invoking yet another component. Here's an example to illustrate my point:
// page.tsx
"use server";
export default async function Page() {
const data = await fetchData();

return (
<Suspense fallback={<Loading/>}> // This Suspense is not working here.
<INeedSomeData data={data}/>
</Suspense>
)
}

// INeedSomeData.tsx
"use client";
export const INeedSomeData = ({data}) => {
// Component implementation
}
// page.tsx
"use server";
export default async function Page() {
const data = await fetchData();

return (
<Suspense fallback={<Loading/>}> // This Suspense is not working here.
<INeedSomeData data={data}/>
</Suspense>
)
}

// INeedSomeData.tsx
"use client";
export const INeedSomeData = ({data}) => {
// Component implementation
}
In this setup, <Suspense/> isn't aware that INeedSomeData is awaiting the fetched data. So, I'm thinking the better approach is to have the component fetch its data, like this:
// page.tsx
"use server";
export default async function Page() {
return (
<Suspense fallback={<Loading/>}> // This Suspense now works
<IFetchSomeData />
</Suspense>
)
}

// IFetchSomeData.tsx
"use server";
export const IFetchSomeData= async () => {
const data = await getData();
return (
<IRenderData data={data}/>
)
}

// IRenderData.tsx
"use client";
export const IRenderData = ({data}) => {
// Component implementation
}
// page.tsx
"use server";
export default async function Page() {
return (
<Suspense fallback={<Loading/>}> // This Suspense now works
<IFetchSomeData />
</Suspense>
)
}

// IFetchSomeData.tsx
"use server";
export const IFetchSomeData= async () => {
const data = await getData();
return (
<IRenderData data={data}/>
)
}

// IRenderData.tsx
"use client";
export const IRenderData = ({data}) => {
// Component implementation
}
This works, but this makes it necessary for another nested component. Am I getting this pattern wrong? I'd love some opinions, thanks!
2 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 2/15/2024 in #questions
App directory fetch data from endpoint with query parameters
Hi, i'm dipping my toes into the app directory for NextJS and I can't seem to get this working. Essentially, i'd like to fetch some data from my API endpoint applying some conditions to them from my Search Parameters. What is a common pattern to do this? Currently I have my page.tsx:
export default async function Page() {
const params = useParams();
const { data } = await api.data.getData.query({
condition1: params.condition1
});

return (
....
);
}
export default async function Page() {
const params = useParams();
const { data } = await api.data.getData.query({
condition1: params.condition1
});

return (
....
);
}
Which nets me with the beautiful error of:
Unhandled Runtime Error

Error: useParams only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component
Unhandled Runtime Error

Error: useParams only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component
4 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/16/2023 in #questions
What's a good way to "protect" a public TRPC endpoint
I'm working on an app with a Google Maps API endpoint accessible from our frontend. My challenge is preventing external abuse of this endpoint. I've planned rate limiting, but I'm looking for more ways to keep this endpoint secure and within our app's scope. Any tips or experiences in safeguarding such an API? Your advice would be super helpful! Thanks!
35 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/6/2023 in #questions
Sitemaps - Is there something fundamental i'm misunderstanding about sitemaps?
Hello! I'm currently exploring how to best generate dynamic sitemaps for a Next.js-powered website. I stumbled upon the next-sitemap package (https://www.npmjs.com/package/next-sitemap), which seems like a robust solution for my needs. I can either use this package or handcraft the XML, but I'm leaning towards the former for convenience. Here's a snippet of what my sitemap generation looks like:
// pages/server-sitemap.xml/index.tsx
import { getServerSideSitemapLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

const fields = [
{
loc: 'https://example.com', // Absolute url
lastmod: new Date().toISOString(),
// changefreq
// priority
},
{
loc: 'https://example.com/dynamic-path-2', // Absolute url
lastmod: new Date().toISOString(),
// changefreq
// priority
},
]

return getServerSideSitemapLegacy(ctx, fields)
}

// Default export to prevent next.js errors
export default function Sitemap() {}
// pages/server-sitemap.xml/index.tsx
import { getServerSideSitemapLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

const fields = [
{
loc: 'https://example.com', // Absolute url
lastmod: new Date().toISOString(),
// changefreq
// priority
},
{
loc: 'https://example.com/dynamic-path-2', // Absolute url
lastmod: new Date().toISOString(),
// changefreq
// priority
},
]

return getServerSideSitemapLegacy(ctx, fields)
}

// Default export to prevent next.js errors
export default function Sitemap() {}
Could someone clarify when this code is actually executed? I know getServerSideProps runs server-side on each request, but does this mean that a user or a search engine bot needs to navigate to /server-sitemap-index.xml for the sitemap to be generated? What if that never happens or takes a long time? I am a bit confused on how this'll work in practice. Appreciate any insights!
2 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 11/4/2023 in #questions
Enhancing Performance with Pre-fetching Paginated Queries in tRPC
Hello, I'm currently focused on boosting the performance of a website that incorporates tRPC. Our setup involves a paginated query that fetches a list of items based on the active page, which is determined by the query parameters:
const { page } = router.query;
const { data, isLoading } = trpc.getMany.useQuery(
{
where: {
createdAt: {
gte: twoWeeksAgo,
},
},
page: Number(page) || 1,
},
{
refetchOnMount: false,
refetchOnWindowFocus: false,
}
);
const { page } = router.query;
const { data, isLoading } = trpc.getMany.useQuery(
{
where: {
createdAt: {
gte: twoWeeksAgo,
},
},
page: Number(page) || 1,
},
{
refetchOnMount: false,
refetchOnWindowFocus: false,
}
);
Take, for example, the scenario where we are on page = 1. This query will retrieve a list of items specifically for that page. What I aim to achieve is to have the data for page = 2 pre-fetched and stored in the react-query cache in the background. This way, when users navigate to page 2, the transition is seamless with the data appearing instantly, leveraging react-query's caching capabilities. Is there an established pattern or best practice to prefetch the data for the next page without rendering it, thus ensuring that the data is readily available and the user experience is smooth? Any guidance or suggestions would be greatly appreciated. Thank you!
2 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 10/25/2023 in #questions
Long minimumCacheTTL in next.config
Hey everyone! I'm contemplating the idea of setting a really long minimumCacheTTL for scenarios where images rarely, if ever, change. Imagine a massive website with around 100,000 static images. Would there be benefits to having a minimumCacheTTL of, say, a year? As far as I grasp, this would keep the optimized image saved on the server's disk (within .next/cache/images) so it wouldn't need re-optimization, saving CPU resources and preventing image loading delays. The obvious trade-off is disk space, but assuming that's not an issue, are there other considerations I might be missing?
2 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 10/17/2023 in #questions
Render either a Sheet, or a Dialog in a streamlined way with Shadcn/ui?
Hi there, i'm dipping my toes into shadcn lately, and i'm really digging it. But a common issue i've been running into, is that often times i'd like to use a Sheet component on mobile, while on desktop i'd like to use a Dialog component. Would there be a way to have a re-usable component that will either render a Dialog or a Sheet, similar to how the Sheet and Dialog function independently? Or do you think I am thinking of this in the wrong way? For context what i'm roughly thinking of:
<DialogOrSheet> // These components would either render a Dialog, or a Sheet, depending on conditions I set it, or alternatively as a prop.
<DialogOrSheetTrigger>Trigger example</DialogOrSheetTrigger>
<DialogOrSheetHeader>
<DialogOrSheetTitle>A cool title</DialogOrSheetTitle>
</DialogOrSheetHeader>
<DialogOrSheetContent>...</DialogOrSheetContent>
</DialogOrSheet>
<DialogOrSheet> // These components would either render a Dialog, or a Sheet, depending on conditions I set it, or alternatively as a prop.
<DialogOrSheetTrigger>Trigger example</DialogOrSheetTrigger>
<DialogOrSheetHeader>
<DialogOrSheetTitle>A cool title</DialogOrSheetTitle>
</DialogOrSheetHeader>
<DialogOrSheetContent>...</DialogOrSheetContent>
</DialogOrSheet>
18 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 9/30/2023 in #questions
Image Memory Leak in NextJS?
Hi, we're running a NextJS application on a VPS, and from the looks of it the Next Image has a memory leak of some sort? Whenever loading in images, memory increases, which is expected, but it should reduce after the minimumCacheTTL as far as I understand, but it seems it's infinitely caching images in memory (as well as in the file-system, but that's expected). Memory baseline for our application starts at ~200mb, and build up to 1 GB+ overtime when hundreds of images are loaded in, memory is never released. I am also confident it's caused by Next/Image since running it with unoptimized images has zero issues and RAM stays at the baseline forever. I'm wondering if anybody else has run into similar issues, and if there's any known fixes for this?
3 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 9/15/2023 in #questions
Anyone can help me with this React-Hook-Form problem?
Hi, i'm creating a complex form-system using React-Hook-Form, but my handleSubmit's from RHF are not firing for some reason. I have stripped my code down to the bare minimum, and it's still not functioning, is there something I am missing?? The only thing firing off is the console.log("submitting..") but the actual data/errors of the form are not.
const form = useForm<TFormValues>({
resolver: zodResolver(FormSchema),
defaultValues,
});
return (
<form
onSubmit={(e) => {
e.preventDefault();
console.log("Submitting...");
form.handleSubmit(
(data) => {
console.log(data);
},
(errors) => {
console.log(errors);
}
);
}}
>
<input type='text' {...form.register('testName')} />
<input type='submit' />
</form>
const form = useForm<TFormValues>({
resolver: zodResolver(FormSchema),
defaultValues,
});
return (
<form
onSubmit={(e) => {
e.preventDefault();
console.log("Submitting...");
form.handleSubmit(
(data) => {
console.log(data);
},
(errors) => {
console.log(errors);
}
);
}}
>
<input type='text' {...form.register('testName')} />
<input type='submit' />
</form>
Calling form.handleSubmit() programatically will also not work, outside of the event handler itself, so I am unsure where this issue is arising from
3 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 9/13/2023 in #questions
Breaking-border on input fields
No description
8 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 8/14/2023 in #questions
Weird next-auth behaviour
I have a weird issue happening lately with next-auth. Whenever I call signIn('provider') , I get redirected to /api/auth/signin, and if on that page I click on whichever provider, I get redirected again to this same page. No errors are logged, even with debug: true set in nextAuth itself. On localhost, everything runs fine, even with a ngrok setup on top of it. I've already stripped away all of my custom configurations of next-auth, double checked my .env variables which seem to be in line with my production server (that is running fine). And the problem can't lie in the provider itself, as it's happening with every single provider, + email login (which doesn't trigger any of the next-auth stuff, and just redirects me back to /api/auth/signin. Would anybody know where I can continue to debug this? My environment runs on: - VPS setup with NGINX - A subdomain (staging.domain.com) - Cloudflare
28 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 8/11/2023 in #questions
Webstorm & TRPC Errors
3 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 8/10/2023 in #questions
Intellisense unbearably slow
I have a decently large project setup with T3 stack, with a lot of inferred trpc routes. The intellisense is literally almost unusable, and the type checker is unbearably slow. - Getting an import into the "quick fix" takes about 10 seconds on avarage - Getting an error to show in my editor from typescript takes about 6 seconds after a change (checked via ts logs, it's fairly consistent 6seconds). - Intellisense stays at loading for a good 3-4 seconds before anything even pops up. I have no clue where to debug this. I'd appreciate some pointers on why this is so unbearably slow. Is this just the nature of trpc/prisma/zod or something?? Things I've done: - Disable all extensions - Try it on my home pc as opposed to work laptop. (work laptop is running on arch, pc on windows/wsl2) - Tried fresh node_modules. - Node modules is excluded in ts file, ts strict mode is enabled. - Tried vscode instead of webstorm. Equally slow.
24 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 7/30/2023 in #questions
Anybody got a vitest with T3-app setup?
I'm trying to setup vitest tests with my trpc routes, but after following the official t3 docs (https://create.t3.gg/en/usage/trpc/#sample-integration-test), and the official prisma guide on how to mock the db (https://www.prisma.io/blog/testing-series-1-8eRB5p0Y8o), I am running into the issue of (it seems like) my models not being created. TypeError: Cannot read properties of undefined (reading 'create') Does anybody have any projects that have this setup and working? Been picking my brain on this for a few hours and can't understand why my prisma mock isn't working as expected.
4 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 7/23/2023 in #questions
I want to use Middleware with Database strategy.
Hi, I'd like to use the nextjs middleware using the database sessions strategy for next auth. In the cookies we get the property 'next-auth.session-token', which contains a value of the session's id stored in my database. I could theoretically do a lookup in my DB if this session exists and is linked to a valid user. I'd like some opinions on this, is this a good approach on it? My usecase is securing an admin page for a website, of which I need to acess the user's information in the user table.
export function middleware(req: NextRequest) {
const session = req.cookies.get('next-auth.session-token');
// Here I could do a call to my API endpoint which will perform a lookup on my database
}
export function middleware(req: NextRequest) {
const session = req.cookies.get('next-auth.session-token');
// Here I could do a call to my API endpoint which will perform a lookup on my database
}
Is there a better solution than what i'm currently thinking?
3 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 1/21/2023 in #questions
How is this creating an error?
const createdResult = await ctx.prisma.quizResult.create({
data: {
score,
},
});

⛔⛔Unsafe assignment of an `any` value.eslint@typescript-eslint/no-unsafe-assignment⛔⛔
const createdResult = await ctx.prisma.quizResult.create({
data: {
score,
},
});

⛔⛔Unsafe assignment of an `any` value.eslint@typescript-eslint/no-unsafe-assignment⛔⛔
When I reload typescript server, this error goes away. But this keeps popping up over and over again throughout my codebase, and on others working on this same project as well. What is causing this? This is a fresh codebase in the T3-Stack, nothing weird has been done to it, just using default setup.
16 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 1/8/2023 in #questions
Need help to approach Layout issue
So i've got a Layout wrapper component for my (almost fully) static app - Problem is, this Layout requires certain Static Data, product categories. The way I do it now is every page calls my <Layout categories={categories}/> component with the categories props which are statically fetched on every page's getStaticProps - Is there a good way for me to be able to wrap this Layout component across all pages in _app while still having access to the categories data?
31 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 1/5/2023 in #questions
How to check if type is array?
I have the following interface
interface IFilterOptions {
price: {
min: number,
max: number,
},
item_type: string[],
state: string[],

[key: string]: string[] | {min: number, max: number};
}
interface IFilterOptions {
price: {
min: number,
max: number,
},
item_type: string[],
state: string[],

[key: string]: string[] | {min: number, max: number};
}
How can I check if i'm dealing with the object type or the string[] type while mapping through the key's of IFilterOptions ie:
Object.keys(filterOptions).forEach((filter) => {
if (filter === "price") {
....
return;
} else if (Array.isArray(filterOptions[filter]) && !filterOptions[filter].includes("test"))
❌❌ -> Property 'includes' does not exist on type 'string[] | { min: number; max: number; }' ❌❌
}
});
Object.keys(filterOptions).forEach((filter) => {
if (filter === "price") {
....
return;
} else if (Array.isArray(filterOptions[filter]) && !filterOptions[filter].includes("test"))
❌❌ -> Property 'includes' does not exist on type 'string[] | { min: number; max: number; }' ❌❌
}
});
13 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 12/27/2022 in #questions
NextAuth OAUTH_CALLBACK_ERROR - checks.state argument is missing
Getting this stacktrace after logging in via google provider on nextauth, as soon as I get redirected. Weirdly enough I am logged in though but when trying to access token it's null, and if I refresh page i'm logged out again. What is this and how can I debug this?
11 replies
TTCTheo's Typesafe Cult
Created by Xaohs on 12/24/2022 in #questions
Next Image and Caching. High RAM usage.
Hi, recently i've been looking more closely at my RAM usage on my nextjs droplet. And i've noticed that the RAM on a fresh instance of the app sits at around 150mb (on the node process), but after some time and clicking around on the website it starts racking up to as much as 1.4GB/1.5GB I have available - this dramatically slows down everything. I turned image optimization off, and it never got higher than 300mb with it off. Is this normal? Am I doing something wrong?
44 replies