#ReferenceError: window is not defined

296 messages · Page 1 of 1 (latest)

velvet steppe
#

I have an app that I cleaned up and mostly moved from client side to server side last night thanks to DirtyCajunRice!

Only issue is that on my builds I can't access query parameters, on development I can. I see this in my console logs:

    at n (/Users/berkserbetcioglu/Code/storefront/.next/server/app/[...r]/page.js:1:2996)
    at nM (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:47419)
    at nN (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64674)
    at nI (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:46806)
    at nM (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:47570)
    at nM (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:61663)
    at nN (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64674)
    at nB (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:67657)
    at nF (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:66824)
    at nN (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64990)```

I'm guessing that is the reason. Here is my page.tsx:
```ts
import React from 'react'
import ProductCards from './ProductCards';
import { ProductSearchParams } from '@/types/products';

interface Props {
  searchParams: ProductSearchParams
}

export default function Home({ searchParams }: Props) {
  console.log("searchParams", searchParams);
  return (
    <main>
      <ProductCards {...searchParams} />
    </main>
  );
}```

types.tsx:
```ts
export const allSearchParams =  ['r', 'search', 'genders',  'sizes', 'conditions', 'countries', 'brands', 'pages'] as const;
export type ProductSearchParam = typeof allSearchParams[number];
export type ProductSearchParams = Record<ProductSearchParam, string | string[]>;
export interface Product {
    title: string;
    brands: string[];
    actions: string[];
    status: string | null;
    genders: string[];
    sizes: string[];
    categories: string[];
    price: number | null;
    currency: string | null;
    countries: string[];
    images: string[];
    conditions: string[];
    colors: string[];
    shipping_info: string | null;
    search_keywords: string | null;
    timestamp: number; // in seconds
    source: string;
    reddit_subreddit: string;
    reddit_author: string;
    reddit_post_id: string | null;
    reddit_thread_id?: string | null;
    reddit_comment_id: string | null;
    listing_number: number;
}```

First few lines of  ProductCards.tsx
```ts
import React, { Suspense } from 'react'
import Link from 'next/link'
import SearchContainer from './SearchContainer';
import { CustomImage, DefaultImage } from './image';
import products from '@/json/listings.json'
import { allSearchParams, ProductSearchParam, ProductSearchParams, Product } from '@/types/products';
import { redirect } from 'next/navigation'
import { CheckBox } from './checkbox';

function sanitize(params: ProductSearchParams) {
  const stringsOnly = Object.fromEntries(Object.entries(params).map(([k, v]) => [k, Array.isArray(v) ? v[0] : v]));
  return {... stringsOnly, pages: Number(stringsOnly.pages)} as Record<Exclude<ProductSearchParam, 'pages'>, string> & { pages: number };
}

const ProductCards = (props: ProductSearchParams) => {
  const initialParams = sanitize(props)
  console.log("Initial Params:", initialParams)```
Can share anything else that helps!
grim cradleBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

velvet steppe
#

I'm seeing that something related to useEffect() needs to be done here, but unfortunately I am a bit too new to quickly understand

elder jasper
velvet steppe
#

Yup!

elder jasper
velvet steppe
#

SearchContainer has window:

'use client'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import { useState } from 'react'

const SearchContainer = () => {

    // NextJs Navigation
    const router = useRouter()
    const searchParams = useSearchParams()
    const pathname = usePathname()
    let queryParams: URLSearchParams;

    // React States
    const [search, setSearch] = useState(searchParams.get('search') || '')

    // Handle Submitting
    const handleSubmit = (e: any) => {
        e.preventDefault()
        if (typeof window !== "undefined") {
          queryParams = new URLSearchParams(window.location.search);
        }

        queryParams.delete("pages");
        if (search === '') {
            queryParams.delete('search');
        } else {
            queryParams.set('search', search);
        }
        const path = window.location.pathname + "?" + queryParams.toString();
        router.push(path);
    }

    const removeSearch = (e: any) => {
        router.push(pathname)
        return
    }

    return (
        <form>
            <input className='border border-gray-400 rounded-md p-1' placeholder='Search' onChange={(e) => setSearch(e.target.value)} defaultValue={search}/>
            <button className='border border-gray-400 rounded-md p-1 m-2 hover:bg-blue-100' type='submit' onClick={handleSubmit}>🔍</button>
            <button type='submit' onClick={removeSearch}>✖️</button>
        </form>
    )
}

export default SearchContainer```
#

I call this in ProductCards.tsx

elder jasper
velvet steppe
#

Yup

velvet steppe
#

just call it in the return


      <div className="flex justify-center items-center">
        <Suspense>
          <SearchContainer/>
        </Suspense>
      </div>```
#

Even when I take out SearchContainer I get the same error

elder jasper
#

I don't see any issue yet

velvet steppe
#

I am not

elder jasper
velvet steppe
#

In my terminal

#
    at n (/Users/berkserbetcioglu/Code/storefront/.next/server/app/[...r]/page.js:1:2996)
    at nM (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:47419)
    at nN (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64674)
    at nI (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:46806)
    at nM (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:47570)
    at nM (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:61663)
    at nN (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64674)
    at nB (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:67657)
    at nF (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:66824)
    at nN (/Users/berkserbetcioglu/Code/storefront/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64990)
elder jasper
#

npm run build?

velvet steppe
#

I think even the page.tsx has the error

#

After build

#

npm run

#

Not dev

elder jasper
#

no error with npm run dev?

velvet steppe
#

npm start*

velvet steppe
#

I see a very long warning

elder jasper
#

do you have a route at app/[...r]/page.tsx

velvet steppe
#

I do!

elder jasper
#

show the code on that page

velvet steppe
#

import React from 'react'
import { redirect } from 'next/navigation';
import { usePathname } from 'next/navigation'

export default function SubredditRedirect() {
    const pathname = usePathname()
    const queryParams = new URLSearchParams(window.location.search);
    if (queryParams.toString()) {
        redirect('/' + "?r=" + pathname.split('/')[2] + "&" + queryParams.toString())
    } else {
        redirect('/' + "?r=" + pathname.split('/')[2])
    }
}```
elder jasper
#

const queryParams = new URLSearchParams(window.location.search);

velvet steppe
#

Is that the line with the bug

elder jasper
#

yes

#

change to const queryParams = useSearchParams()

#

and wrap this component with Suspense

#

or is this a page?

velvet steppe
#

Its a page

#

It redirects

velvet steppe
#

I turn /r/name to ?r=name

#

It looks like that error is gone by my query params still aren't working in the app on build

elder jasper
#

remove 'use client'

velvet steppe
#

On it

velvet steppe
elder jasper
elder jasper
velvet steppe
#

it can be anything

#

Any subreddit name

elder jasper
#

what is the file path?

#

I mean if they go to url /r

velvet steppe
#

/app/[...r]/page.tsx

#

That one

#

?

elder jasper
#

yes

#

so what is the name if they go to /r ?

#

404?

velvet steppe
#

Yes

elder jasper
# velvet steppe Yes
import { notFound, redirect } from "next/navigation";

export default function SubredditRedirect({
  params,
  searchParams,
}: {
  params: string[];
  searchParams: { [key: string]: string };
}) {
  if (params.length < 1) notFound()
  if (searchParams) {
    redirect(
      "/" +
        "?r=" +
        params[1] +
        "&" +
        new URLSearchParams(searchParams).toString()
    );
  } else {
    redirect("/" + "?r=" + params[1]);
  }
}
velvet steppe
#

Sorry I just understood 🙂

#

Now I get /?r=undefined&

#

When I go to /r/a

elder jasper
# velvet steppe Now I get /?r=undefined&
import { notFound, redirect } from "next/navigation";

export default function SubredditRedirect({
  params,
  searchParams,
}: {
  params: {r: string[]};
  searchParams: { [key: string]: string };
}) {
  if (params.r.length < 1) notFound()
  if (searchParams) {
    redirect(
      "/" +
        "?r=" +
        params.r[1] +
        "&" +
        new URLSearchParams(searchParams).toString()
    );
  } else {
    redirect("/" + "?r=" + params.r[1]);
  }
}
#

yeah, forgot it is in r

velvet steppe
#

Yup that worked!

#

But the app still doesnt work

elder jasper
velvet steppe
#

So I have these filters that are checkboxes, they don't update the products or show which ones are checked

#

On dev they do

elder jasper
velvet steppe
elder jasper
#

where is your checkbox?

velvet steppe
#

In ProductCards.tsx

elder jasper
#

just passing default value to defaultValue

velvet steppe
#

Trying!

#

Didn't seem to work

#

But I also have a search box and a button

#

None work

#

The work in the sense that they create a new query param, but they delete all old ones

#

And they don't reflect the existing ones

#

Checkbox is defined here:


import {  DetailedHTMLProps, InputHTMLAttributes} from "react";

export const CheckBox = (props: DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>) => {
  const onClick = (e: any) =>  e.currentTarget.form?.requestSubmit();
  return <input {...props} onClick={onClick} />
}```
elder jasper
# velvet steppe Didn't seem to work
  async function submitForm(formData: FormData) {
    'use server';
    const newSearchParams = new URLSearchParams();
    allSearchParams.forEach(p => {
      const opts = formData.getAll(p)
      if (opts.length) {
        console.log("Form Data:", p, opts.join(","));
        newSearchParams.append(p, opts.join(","));
      }
    })
    if (initialParams.search) {
      newSearchParams.append("search", initialParams.search)
    }
    redirect(`?${newSearchParams.toString()}`)
  }
#

what are you trying to do

velvet steppe
#

Just keep adding query params, either by , if part of the same category or a new one

elder jasper
velvet steppe
#

formData seemed to have it in dev

elder jasper
#

try again in dev

#

but I don't understand what you are trying to do here lol

velvet steppe
elder jasper
#

<form>

#

remove the action there and try again

velvet steppe
#

But then it cant work

#

Then it seems to append a new query param

#

I want ?sizes=1,2,3

#

Not ?sizes=1&sizes=2

elder jasper
# velvet steppe Not ?sizes=1&sizes=2
  async function submitForm(e: FormEvent<HTMLFormElement>) {
    const formData = new FormData(e.currentTarget)
    const newSearchParams = new URLSearchParams();
    allSearchParams.forEach(p => {
      const opts = formData.getAll(p)
      if (opts.length) {
        console.log("Form Data:", p, opts.join(","));
        newSearchParams.append(p, opts.join(","));
      }
    })
    if (initialParams.search) {
      newSearchParams.append("search", initialParams.search)
    }
    redirect(`?${newSearchParams.toString()}`)
  }


  <form onSubmit={submitForm}>
velvet steppe
#

trying!

velvet steppe
elder jasper
velvet steppe
#

It should be (misspoke)

#

No 'use client'

elder jasper
#

add it

velvet steppe
#

Sorry

#

I was thinking this should be a server component

#

Can it be?

#

That the whole conversion DirtyCajunRice helped me make

elder jasper
#

try to see if it work first

velvet steppe
#

Sure

elder jasper
#

it was ignoring initialParams.search right?

velvet steppe
#

When making client I get this:

Error: 
  × It is not allowed to define inline "use server" annotated Server Actions in Client Components.```
#

I have some "use server"

elder jasper
#

no

#

you have 'use server'; in updatePage

velvet steppe
elder jasper
#

change it back to action

velvet steppe
elder jasper
elder jasper
velvet steppe
#

Now action is giving an error

#
  <form action={function} children=...>```
velvet steppe
#

Right now everything works on dev

elder jasper
#

what is not working in prod?

velvet steppe
#

Only adds a query param to the url. Deletes all old ones. Also existing query params are not reflected on my page

#

It's like the data isn't coming in

elder jasper
#

could you show the url in dev and prod

velvet steppe
#

Sure

#

But in dev things are happening on the page

#

In prod nothing is and it keeps overwriting

elder jasper
velvet steppe
#

Checking

velvet steppe
#

Just the new selection

#

But the old selection isn't default checked anyway

elder jasper
# velvet steppe Form Data: sizes 3L
async function submitForm(formData: FormData) {
    'use server';
    console.log(Object.fromEntries(formData))

add this console.log and check it in prod

velvet steppe
elder jasper
velvet steppe
#

Data isn't coming in

elder jasper
velvet steppe
#

Checking

#

It is checked

velvet steppe
#

But it's not just checkboxes, also searchbox and button

elder jasper
#

I think you should make the form in client component

velvet steppe
elder jasper
#

and render the client form in it

#

and pass the data the form need

velvet steppe
#

Like right now, if I manually update query params - the server component can't access all the data

#

It's not getting passed through

elder jasper
#

what data?

elder jasper
velvet steppe
#

When I go to http://localhost:3000/?sizes=8 that sizes information should filter products - it doesn't

#

Unrelated to checkboxes

elder jasper
#

did you use the searchParams object?

#

to query your data

velvet steppe
#

No I use initialParams

#
import ProductCards from './ProductCards';
import { ProductSearchParams } from '@/types/products';

interface Props {
  searchParams: ProductSearchParams
}

export default function Home({ searchParams }: Props) {

  console.log("searchParam", searchParams);
  return (
    <main>
      <ProductCards {...searchParams} />
    </main>
  );
}```
#
function sanitize(params: ProductSearchParams) {
  const stringsOnly = Object.fromEntries(Object.entries(params).map(([k, v]) => [k, Array.isArray(v) ? v[0] : v]));
  return {... stringsOnly, pages: Number(stringsOnly.pages)} as Record<Exclude<ProductSearchParam, 'pages'>, string> & { pages: number };
}

const ProductCards = (props: ProductSearchParams) => {
  const initialParams = sanitize(props)```
#

The variable after sanitization

elder jasper
velvet steppe
#

On prod

#

It doesn't log anything either, just static

elder jasper
velvet steppe
elder jasper
#

check the build report

velvet steppe
#

But everything else loads the same

#

Will share build

elder jasper
#

it should tell you the route is dynamic or static

velvet steppe
#
> [email protected] build
> next build

   ▲ Next.js 14.1.0
   - Environments: .env

   Creating an optimized production build ...

🌼   daisyUI 4.6.0
├─ ✔︎ 1 theme added        https://daisyui.com/docs/themes
╰─ ★ Star daisyUI on GitHub    https://github.com/saadeghi/daisyui

 ✓ Compiled successfully

./app/ProductCards.tsx
402:31  Warning: Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element  @next/next/no-img-element
402:31  Warning: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images.  jsx-a11y/alt-text
410:31  Warning: Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element  @next/next/no-img-element
410:31  Warning: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images.  jsx-a11y/alt-text

./app/image.tsx
68:12  Warning: Image elements must have an alt prop, either with meaningful text, or an empty string for decorative images.  jsx-a11y/alt-text

info  - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules
 ✓ Linting and checking validity of types    
 ✓ Collecting page data    
   Generating static pages (0/6)  [    ]searchParam {}
Initial Params: { pages: NaN }
Initial Params: { pages: NaN }
Current Page: 1
searchParam {}
Initial Params: { pages: NaN }
Initial Params: { pages: NaN }
Current Page: 1
 ✓ Generating static pages (6/6) 
 ✓ Collecting build traces    
 ✓ Finalizing page optimization    

Route (app)                              Size     First Load JS
┌ ○ /                                    6.39 kB        97.3 kB
├ ○ /_not-found                          0 B                0 B
├ ○ /...not_found                        141 B          84.3 kB
└ λ /[...r]                              141 B          84.3 kB
+ First Load JS shared by all            84.2 kB
  ├ chunks/69-9c3c64001cadfd4c.js        28.9 kB
  ├ chunks/fd9d1056-534a3af521b04580.js  53.4 kB
  └ other shared chunks (total)          1.9 kB


○  (Static)   prerendered as static content
λ  (Dynamic)  server-rendered on demand using Node.js```
elder jasper
#

ok its dynamic

velvet steppe
#

How can you tell?

elder jasper
#

λ (Dynamic) server-rendered on demand using Node.js

#
import React from 'react'
import ProductCards from './ProductCards';
import { ProductSearchParams } from '@/types/products';

interface Props {
  searchParams: ProductSearchParams
}

export default function Home({ searchParams }: Props) {

  console.log("searchParam", searchParams);
  return (
    <main>
      <ProductCards key={JSON.stringify(searchParams)} {...searchParams} />
    </main>
  );
}
velvet steppe
#

But how can you tell the specific pahe?

elder jasper
#

you have only one route

velvet steppe
#

Cool

elder jasper
#

and how do you fetch the data?

velvet steppe
#

Works now!

velvet steppe
elder jasper
#

oh your home page is static

#

┌ ○ /

velvet steppe
#

Latest:

┌ λ /                                    6.39 kB        97.3 kB
├ ○ /_not-found                          0 B                0 B
├ ○ /...not_found                        141 B          84.3 kB
└ λ /[...r]                              141 B          84.3 kB
+ First Load JS shared by all            84.2 kB
  ├ chunks/69-9c3c64001cadfd4c.js        28.9 kB
  ├ chunks/fd9d1056-534a3af521b04580.js  53.4 kB
  └ other shared chunks (total)          1.9 kB


○  (Static)   prerendered as static content
λ  (Dynamic)  server-rendered on demand using Node.js```
#

So it changed

elder jasper
elder jasper
velvet steppe
#

In the main page

elder jasper
#

so everything work now?

#

it was because your home page is static generated

velvet steppe
#

Yup! Quick question, my dropdowns close after each selection - is there a simple way to keep it open?

velvet steppe
elder jasper
#

@woven ether could you help? 😆

velvet steppe
woven ether
elder jasper
#

lol

elder jasper
#

could you help with this

#

I gotta go lol

woven ether
#

Sure I’ll do my best!

elder jasper
#

I will mark your answer as solution

#

thanks, later both

woven ether
#

Sorry can I get a tldr while I read all of this

velvet steppe
#

Later!

#

So I have dropdowns with checkboxes

#

Every time I check/uncheck - the dropdown closes

#

I would like the user to be able to keep selecting

woven ether
#

Ok are you using a UI library?

velvet steppe
#

I use DaisyUI

#

And tailwind

woven ether
#

Ok gimme 1 min

velvet steppe
woven ether
#

Does it only happen if there are checkboxes in the dropdown? Does it happen with buttons and other interactive elements?

velvet steppe
woven ether
#

Can you show me the code that has your checkboxes in please

velvet steppe
woven ether
#

Does it happen if you click an area of the dropdown that doesn’t have a checkbox?

velvet steppe
#

I define CheckBox here:

'use client';

import {  DetailedHTMLProps, InputHTMLAttributes} from "react";

export const CheckBox = (props: DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>) => {
  const onClick = (e: any) =>  e.currentTarget.form?.requestSubmit();
  return <input {...props} onClick={onClick} />
}```
velvet steppe
#

Also after I click a button

woven ether
#

Ahhhh I see

#

That shouldn’t be happening, something is causing the entire page to refresh which shouldn’t be happening if you didn’t intend it to

velvet steppe
#

It's a server side component

woven ether
#

This will be tricky to diagnose without looking at all of your code but essentially clicking buttons or checkboxes should not be refreshing the page

#

What happens when you click the checkbox? Can I see your handler function and what it calls

velvet steppe
#

Sure

#

This check if it's checkedts function checkHandler(param: ProductSearchParam, values: any) { if (!initialParams[param] || param === 'pages') { return false; } const options = initialParams[param].split(',') switch (param) { case "r": return options.includes(values['subreddit_name']); case "genders": return options.includes(values['gender']); case "sizes": return options.includes(values['size']); case "conditions": return options.includes(values['condition']); case "countries": return options.includes(values['country']); case "brands": return options.includes(values['brand']); default: return false; } }

#

Then I got ts async function submitForm(formData: FormData) { 'use server'; console.log(formData.getAll('sizes')) const newSearchParams = new URLSearchParams(); allSearchParams.forEach(p => { const opts = formData.getAll(p) if (opts.length) { console.log("Form Data:", p, opts.join(",")); newSearchParams.append(p, opts.join(",")); } }) if (initialParams.search) { newSearchParams.append("search", initialParams.search) } redirect(`?${newSearchParams.toString()}`) }

woven ether
#

It’s the redirect I think

velvet steppe
#

Yeah, seems like it

woven ether
#

What are you trying to achieve with the redirect? There might be a better way

velvet steppe
#

Just modifying query params

woven ether
#

I see. One sec

#

There’s a much better way to update the url params

velvet steppe
#

Thats cool

woven ether
#

This will let you keep the page alive and avoid a hard refresh

velvet steppe
#

Is it this: replace(`${pathname}?${params.toString()}`);

#

But that seems to be client side

woven ether
#

Yeah router is client side

#

I don’t think it’s possible to do it like that on the server without causing a full refresh since your manipulating the browser on the client

velvet steppe
#

Yeah I think so too

#

How about not scrolling up during a refresh

woven ether
#

You mean a hard browser refresh? Or like router.refresh

velvet steppe
#

Hard refresh

#

Like I don't do multiple pages

#

I extend the page

#

To show more

#

But user can't tell if jumps to top

woven ether
#

So it’s essentially a single page app?

velvet steppe
#

It is

#

If I refresh my browser manually it doesn't scroll to the top

woven ether
#

It’s not a great approach to have the user needing to refresh the page to show other parts of the app especially in next. You’ll need to do it on the client

velvet steppe
#

I would ideally allow infinite scroll

woven ether
#

You’d need to access the window and define a y position

velvet steppe
#

But on a regular browser, if you just refresh - it keeps the y position

woven ether
#

We should really close this ticket and make a new one for this new issue.

woven ether
velvet steppe
#

Sounds good, thanks so much!

woven ether
#

No problem

#

Basically redirect doesn’t have a scroll option unfortunately

#

Only link, router.push and router.replace do

velvet steppe
woven ether
#

Link is for navigating to other routes so I’m not sure how it would work given you are doing everything on a single page

#

Help me understand your site more. What is your app doing?

velvet steppe
#

It shows product listed on reddit on a website

#

This is the client rendered live version

#

What if I just use <Link> with a prefilled link to the same page with a new query paramete

woven ether
#

You’d be much better off just invalidating the cache of your fetch when the user changes the url params

#

You don’t need to reroute to do what you’re trying to do

#

Are you using fetch?

#

The guide I shared earlier shows a perfect solution to your shop. I’m doing the same on my e-commerce sites

velvet steppe
#

This is the function that updates the page numbers:


  async function updatePage(formData: FormData) {
    'use server';
    console.log("Update Page.")
    console.log("Form Data:", formData)
    const newSearchParams = new URLSearchParams();
    allSearchParams.forEach(p => {
      const opts = formData.getAll(p)
      if (opts.length) {
        console.log("Form Data:", p, opts.join(","));
        newSearchParams.append(p, opts.join(","));
      }
    })
    
    if (initialParams.search) {
      newSearchParams.append("search", initialParams.search)
    }
    newSearchParams.set("pages", ((initialParams.pages || 1) + 1).toString())

    redirect(`?${newSearchParams.toString()}`)
  }```
woven ether
#

You should try revalidatePath or revalidateTag

velvet steppe
#

I'm not familiar with those

woven ether
#

When you change your search params the data will become stale because the app hasn’t been told that the data is stale so there was no need to fetch it again. If you call revalidatePath it will trigger the fetch to run again with the new parameters

#

In a nutshell.

velvet steppe
#

Cool, will do reseach. Thanks!

#

Closing this one

woven ether
#

Cheers