Man @StarWarsOutlaws is the game I didn't know I needed my whole life. Its like Fallout in space with all the weird Star Wars aliens you know and love.
This is my life now 馃槀 10/10
I'm a thieving, double crossing, space pirate with a bounty on my head 馃槑
Interceptors wrap the method call.
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(ctx: ExecutionContext, next: CallHandler) {
const now = Date.now()
return next.handle().pipe(
tap(() => console.log(`done in ${Date.now() - now}ms`))
)
}
}
Use for logging, caching, response mapping. RxJS operators give you the result stream.
#NestJS #WebDev
Testing is first-class.
const module = await Test.createTestingModule({
controllers: [UsersController],
providers: [{ provide: UsersService, useValue: mockService }],
}).compile()
const app = module.createNestApplication()
await app.init()
Override providers with mocks. Supertest for HTTP. Vitest is the new default in Nest 12 ESM projects.
#NestJS #WebDev
Guards decide if a request may continue.
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(ctx: ExecutionContext): boolean {
const req = ctx.switchToHttp().getRequest()
return !!req.user
}
}
@UseGuards(AuthGuard) on routes or controllers. Reflector reads metadata for role checks.
#NestJS #WebDev
Services hold the business logic. Controllers stay thin.
@Injectable()
export class UsersService {
constructor(private readonly db: DatabaseService) {}
async findOne(id: string) {
return this.db.user.find(id)
}
}
@Inject the dependencies. No direct HTTP knowledge inside the service.
#NestJS #WebDev
The Next.js 16 stuff teams still skip:
- cacheComponents + 'use cache'
- cacheLife / cacheTag / updateTag
- Suspense holes for PPR
- Server Actions instead of form route handlers
- await params and searchParams
- proxy.ts instead of middleware.ts
- forbidden() / unauthorized()
- next/font + Image priority on the LCP
- after() for non-blocking work
- generateMetadata
Ship one of these this week. Stop wrapping a fetch in useEffect.
#NextJS #WebDev
Parallel routes are slots, not nested pages you hope will line up.
app/@modal/(.)photo/[id]/page.tsx
app/@feed/page.tsx
app/layout.tsx // receives { modal, feed, children }
default.tsx is required or a hard refresh 404s the slot. Intercepting routes (.) keep the list mounted while the photo opens as a modal.
#NextJS #WebDev
generateStaticParams is the static set, not a cache hint.
export async function generateStaticParams() {
const posts = await db.post.listSlugs()
return posts.map((p) => ({ slug: p.slug }))
}
Build knows those URLs. Unknown slugs can still render dynamically. Empty array means "do not prerender this segment."
#NextJS #WebDev
connection() opts a subtree into request time. On purpose.
import { connection } from 'next/server'
export async function Personalized() {
await connection()
const session = await cookies()
return <p>{session.get('uid')?.value}</p>
}
Calling cookies() or headers() already does this. connection() is the explicit version when the dynamic bit is not a request API. Do not sprinkle it on the layout.
#NextJS #WebDev
after() is the work that should not block the response.
import { after } from 'next/server'
export async function POST(request: Request) {
const payload = await request.json()
after(() => logEvent(payload))
return Response.json({ ok: true })
}
Analytics, audit rows, email enqueue. The client already has the answer. Do not await the side effect on the critical path.
#NextJS #WebDev
Link prefetches the route. prefetch={false} when the list is huge.
import Link from 'next/link'
<Link href={`/blog/${slug}`} prefetch={false}>{title}</Link>
Default prefetch on viewport is why the dashboard feels instant and why a 200-row table hammers the server. Turn it off on low-intent links.
#NextJS #WebDev
proxy.ts replaced middleware.ts.
// proxy.ts
export function proxy(request: NextRequest) {
const token = request.cookies.get('session')
if (!token) return NextResponse.redirect(new URL('/login', request.url))
return NextResponse.next()
}
Auth gate and rewrites live here. Do not fetch your database in the proxy. Check a cookie, then do the work in the server component.
#NextJS #WebDev
forbidden() and unauthorized() are the status, not a redirect to /login disguised as a 200.
import { forbidden, unauthorized } from 'next/navigation'
if (!session) unauthorized()
if (!session.isAdmin) forbidden()
Pair with unauthorized.tsx and forbidden.tsx. A redirect() to the login page is navigation. These are HTTP.
#NextJS #WebDev



















