[🐞] useTask, useVisibleTask runs even if the component is not returned in layout.tsx
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 22.1k
- Forks
- 1.4k
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 52
Description
Which component is affected?
Qwik Runtime
Describe the bug
Qwik with Qwik City layout.tsx has issues with useTask, useVisibleTask .
Reproduction
https://stackblitz.com/edit/vitejs-vite-5mrs5yau?file=src%2Froutes%2Findex.tsx
Steps to reproduce
Project setup
src/
- contexts.ts
- root.tsx
- routes/
- index.tsx
- layout.tsx
contexts.ts
import { Signal, createContextId } from '@builder.io/qwik';
export const LoadingContext = createContextId<Signal<boolean>>('app.LoadingContext');
export const SomeContext = createContextId<Signal<boolean>>('app.SomeContext');
root.tsx
const loading = useSignal(true);
useContextProvider(LoadingContext, loading);
const someData = useSignal(false);
useContextProvider(SomeContext, someData);
useVisibleTask$(async () => {
console.log('Loading...');
someData.value = true;
await new Promise((resolve) => setTimeout(resolve, 500));
loading.value = false;
console.log('Loading done');
});
return (
<QwikCityProvider>
<head>
<meta charset="utf-8" />
{!isDev && (
<link
rel="manifest"
href={`${import.meta.env.BASE_URL}manifest.json`}
/>
)}
<RouterHead />
</head>
<body lang="en">
<RouterOutlet />
</body>
</QwikCityProvider>
);
layout.tsx
import { component$, Slot, useContext } from '@builder.io/qwik';
import { LoadingContext } from '~/contexts';
export default component$(() => {
const loading = useContext(LoadingContext);
if (loading.value) {
return <div>Loading...</div>;
}
return <Slot />;
});
Issue 1
index.tsx
import { component$, useTask$, useVisibleTask$ } from '@builder.io/qwik';
const NestedComp = component$(() => {
useTask$(() => {
console.log('Component useTask: NestedComp');
});
useVisibleTask$(() => {
console.log('Component useVisibleTask: NestedComp');
});
return <div>NestedComp</div>;
});
export default component$(() => {
useTask$(() => {
console.log('Component useTask: index');
});
useVisibleTask$(() => {
console.log('Component useVisibleTask: index');
});
return (
<>
<NestedComp />
</>
);
});
expected console output:
Loading...
Loading done
Component useVisibleTask: index
Component useVisibleTask: NestedComp
current console output:
Loading...
Component useVisibleTask: index
Loading done
Component useVisibleTask: NestedComp
Issue 1 (with a content in the index.tsx component)
index.tsx
import { component$, useTask$, useVisibleTask$ } from '@builder.io/qwik';
const NestedComp = component$(() => {
useTask$(() => {
console.log('Component useTask: NestedComp');
});
useVisibleTask$(() => {
console.log('Component useVisibleTask: NestedComp');
});
return <div>NestedComp</div>;
});
export default component$(() => {
useTask$(() => {
console.log('Component useTask: index');
});
useVisibleTask$(() => {
console.log('Component useVisibleTask: index');
});
return (
<>
<div>Hello</div>
<NestedComp />
</>
);
});
current == expected console output:
Loading...
Loading done
Component useVisibleTask: index
Component useVisibleTask: NestedComp
Issue 2
Conditional rendering on NestedComp
index.tsx
import {
component$,
useContext,
useTask$,
useVisibleTask$,
} from '@builder.io/qwik';
import { SomeContext } from '~/contexts';
const NestedComp = component$(() => {
useTask$(() => {
console.log('Component useTask: NestedComp');
});
useVisibleTask$(() => {
console.log('Component useVisibleTask: NestedComp');
});
return <div>NestedComp</div>;
});
export default component$(() => {
const someData = useContext(SomeContext);
useTask$(() => {
console.log('Component useTask: index');
});
useVisibleTask$(() => {
console.log('Component useVisibleTask: index');
});
return <>{someData.value && <NestedComp />}</>;
});
expected console output:
Loading...
Loading done
Component useVisibleTask: index
Component useTask: NestedComp
Component useVisibleTask: NestedComp
current console output:
Loading...
Component useVisibleTask: index
Component useTask: NestedComp
Component useVisibleTask: NestedComp
Loading done
Issue 2 (with a content in the index.tsx component)
index.tsx
import {
component$,
useContext,
useTask$,
useVisibleTask$,
} from '@builder.io/qwik';
import { SomeContext } from '~/contexts';
const NestedComp = component$(() => {
useTask$(() => {
console.log('Component useTask: NestedComp');
});
useVisibleTask$(() => {
console.log('Component useVisibleTask: NestedComp');
});
return <div>NestedComp</div>;
});
export default component$(() => {
const someData = useContext(SomeContext);
useTask$(() => {
console.log('Component useTask: index');
});
useVisibleTask$(() => {
console.log('Component useVisibleTask: index');
});
return (
<>
<div>Hello</div>
{someData.value && <NestedComp />}
</>
);
});
expected console output:
Loading...
Loading done
Component useVisibleTask: index
Component useTask: NestedComp
Component useVisibleTask: NestedComp
current console output:
Loading...
Component useTask: NestedComp
Component useVisibleTask: NestedComp
Loading done
Component useVisibleTask: index
System Info
Stackblitz
System:
OS: Linux 5.0 undefined
CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 0 Bytes / 0 Bytes
Shell: 1.0 - /bin/jsh
Binaries:
Node: 22.22.3 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 10.8.2 - /usr/local/bin/npm
pnpm: 8.15.6 - /usr/local/bin/pnpm
npmPackages:
@builder.io/qwik: ^1.20.0 => 1.20.0
@builder.io/qwik-city: ^1.20.0 => 1.20.0
typescript: 5.4.5 => 5.4.5
undici: * => 8.5.0
vite: 7.3.1 => 7.3.1
My PC
System:
OS: Windows 11 10.0.26200
CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12700K
Memory: 3.54 GB / 15.76 GB
Binaries:
Node: 26.4.0 - C:\Users\doong\apps\nodejs\node.EXE
npm: 11.17.0 - C:\Users\doong\apps\nodejs\npm.CMD
pnpm: 11.9.0 - C:\Users\doong\AppData\Local\pnpm\bin\pnpm.CMD
Deno: 2.9.0 - C:\Users\doong\.deno\bin\deno.EXE
Browsers:
Chrome: 149.0.7827.201
Edge: Chromium (149.0.4022.98)
Firefox: 152.0.3 - C:\Program Files\Mozilla Firefox\firefox.exe
Internet Explorer: 11.0.26100.8115
npmPackages:
@builder.io/qwik: ^1.20.0 => 1.20.0
@builder.io/qwik-city: ^1.20.0 => 1.20.0
typescript: 5.4.5 => 5.4.5
undici: ^8.5.0 => 8.5.0
vite: 7.3.1 => 7.3.1
Additional Information
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked StackBlitz reproduction and the shown root.tsx, routes/layout.tsx, and routes/index.tsx files; compare hook execution when the layout returns Loading... versus Slot. Trace Qwik Runtime scheduling for useTask$ and useVisibleTask$ with conditional NestedComp rendering, and verify that the observed output matches the expected ordering.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100