← Back to Blogs Developer
LWC Field Guide

Finding the Record Id

Your component is a navigator. The Record Id is the pin it's navigating to. Drop the wrong pin — or none at all — and it wanders. Here's how to drop the right one, five different ways.

c-component navigating → recordId 001…ABCdE

The Record Id is the one value an LWC can't work without. It's the unique key for a single record — an Account, a Contact, a custom object row — and it's how your component knows which record it's actually dealing with.

It behaves like the primary key of a database row: every other field hangs off it. A getRecord wire needs it to pull fields. An Apex update needs it to know what to change. Navigation needs it to know where to go. Hand your component a solid Id and the rest clicks into place.

The wrinkle is that there's no one way to get it. How the Id reaches your component depends entirely on where the component is placed — and picking the wrong route is exactly how a component that's flawless on a record page falls apart the moment it's dropped somewhere else.


The intuition

You can't navigate to “somewhere”

Imagine handing someone the best sat-nav in the world and telling them to drive — but never giving them a destination. All that capability, nowhere to point it. They idle at the kerb.

That's a component with no Record Id. It can query, update, render, navigate — but only once someone drops a pin. The pin is the Id. Everything in this guide is just a different way that pin gets dropped onto your component's map.

NO PIN DROPPED c-component recordId = ? ? capable, but going nowhere PIN DROPPED c-component recordId = 001… a destination — query, render, go
Same component, two maps — the pin is the difference between idling and arriving
The one idea

The Record Id is the pin on your component's map. The five routes below are just different ways it gets dropped.


The trailmap

Five routes to the same pin

Here's the lay of the land before the detail. The same component can reach its Id by five different routes, and the route is chosen by context — where the component runs — not by preference. Four are solid. One is a shortcut that tends to strand you.

recordId Record page@api recordId App page / barCurrentPageReference Inside a parentrecord-id attr Custom tab / URLURL parse · shortcut Already in handNavigationMixin
Four reliable routes (purple) and one shortcut that strands you (red) — all aiming at the same pin

Route 01 — the default

The pin comes pre-dropped

On a record page, the pin is already on the map before your component even loads. Declare a public property named exactly recordId, and the Lightning framework recognises the record and fills it in for you. No wiring, no parsing — it simply arrives. This is the right answer roughly nine times in ten.

Use when

Your component sits directly on a record page — Account, Contact, Opportunity, or any custom object.

!
The name is the magic

It must be spelled recordId exactly. Rename it to accountId and nothing gets injected.


Route 02 — off a record page

Read the pin from the trip link

On an app page, the utility bar, a console, or an Experience site, there's no record context to inject — so @api recordId stays empty. Here the pin rides in the page's URL, and the safe way to read it is to wire CurrentPageReference and pull the Id from its state. You never touch the raw URL yourself, which keeps you safe across Classic, Lightning, and future changes.

Use when

The component has no record parent and the Id arrives through the page's URL state.

Custom params work the same way: a link with ?c__targetId=00Q… reads as pageRef.state.c__targetId — still through state, still safe.


Route 03 — nested components

The lead navigator shares coordinates

When a parent owns the record context and coordinates several children — a dashboard showing Contacts, Opportunities, and Cases for one Account — only the parent needs to know how it got the Id. It passes the pin down through a public property, and each child just receives it. The children stay reusable and never have to care where it came from.

Use when

A parent feeds the same Id to several child components and you want them to stay modular.

c-account-dashboard recordId Contacts Opportunities Cases @api recordId @api recordId @api recordId
One pin, owned by the parent, handed to each child through an attribute

parentLwc.html

accountContacts.js — the child receives the Id


Route 04 — the tempting shortcut

Guessing the pin by counting blocks

You can read the browser URL and grab the Id by position — like navigating by “third turn after the petrol station” instead of an actual address. It works on a tidy record-page URL, where the Id sits neatly between the object name and the action. And it strands you the moment the streets change shape.

RECORD PAGE — Id sits at index 6 …force.com lightning r Account 0015g00000ABCdE view parts[6] ✓ lands on the Id APP PAGE — same index, wrong spot …force.com lightning n My_Dashboard ?c__id=00Q… parts[6] ✗ undefined — the Id moved
The Id's position isn't a constant — count on it and the component breaks off the record page
Why to avoid it

The index is a guess. On an app page, utility bar, or console, parts[6] points somewhere else. Routes 01 and 02 are guaranteed by Salesforce; the URL guarantees nothing.


Route 05 — you already have it

You know the pin — just drive there

This route flips the situation. You're not discovering an Id; you're holding one — from Apex, a wire, or a parent — and you want to take the user to that record. NavigationMixin opens the matching record page programmatically. Perfect for a button that jumps straight to an Account.

Use when

You have an Id in hand and want a button or action that navigates to its record page.


At a glance

The five routes, side by side

Same destination, different terrain. The whole skill is matching the route to where your component runs.

RouteBest contextReliability
@api recordIdDirectly on a record pageGuaranteed
CurrentPageReferenceApp page · utility bar · ExperienceGuaranteed
record-id attributeParent feeding child componentsAs solid as the parent
URL parsingLast resort onlyFragile
NavigationMixinYou already hold the IdGuaranteed

Walk the route

Show an Account's contacts in five steps

The most common real build: a component that drops onto an Account page and lists that account's contacts — using the default route and nothing else.

Declare the pin

Add a public property named exactly recordId with the @api decorator.

Place it on the record page

Drop the component onto the Account record page. Salesforce now injects the account's Id automatically.

Wire the related records

Pass '$recordId' into a getRelatedListRecords wire so it refreshes when the Id resolves.

Render it

Feed the wire's result into a lightning-datatable to show names and emails.

Test on a real record

Open any Account — the contacts appear, and the same component works on every Account with no changes.

Account pageinjects Id @api recordId001…ABCdE @wire related$recordId datatablerenders
The end-to-end route: a record page's Id becomes a rendered list of contacts

Pocket guide

Good routes & wrong turns

Good routes

  • On a record page → @api recordId, done.
  • Off a record page → wire CurrentPageReference.
  • Have a parent → let it pass the Id down.
  • Already hold an Id → NavigationMixin.
  • Bind wires to '$recordId' so they refresh.

Wrong turns

  • Renaming the property (must be recordId).
  • Expecting @api recordId to fill off a record page.
  • Slicing the raw URL by index.
  • Reading the Id in connectedCallback too early.
  • Forgetting the $ on a reactive wire.

Field notes

Keep these in your pack

  • The injected property is always recordId — spelling and casing matter.
  • @api recordId only fills on a record page; everywhere else it's empty.
  • Read URL params through pageRef.state, never by slicing window.location.
  • Make wires reactive with '$recordId' so they re-run when the Id arrives.
  • A child only gets the Id if the parent actually binds record-id={recordId}.
  • NavigationMixin is for going to a record, not discovering the current one.

Back to camp

The whole map in a sentence

Strip away the APIs and it's one idea: a component is only as useful as the pin it's given. The Record Id is that pin, and the craft is letting it land the way Salesforce intends — by context, not by guesswork.

On a record page, the pin comes pre-dropped. Off it, read the trip link. With a parent, take the coordinates from the lead. And when you already hold the Id, just drive there. Reach for the URL only when every other route is blocked.

Remember this

Right context → right route → the Id lands in recordId and everything downstream just works.

A Field Guide to the Record Id in LWC

Five ways a Lightning Web Component finds its Record Id — and when to use each. Diagrams original; code illustrative. Pick the route by context, not by habit.

Welcome Back

OR
Don't have an account? Sign up