Next.js visual feedback
From the element you clicked to the component that rendered it
Loopa is source-aware annotation for Next.js. A comment on a captured page can carry the JSX/TSX location that rendered the element, the build it came from and how confident that link is.
Rendered page ↔ TSX
Beyond coordinates
Why screenshot coordinates are not enough
A pin on a screenshot says where someone looked. It does not say which component to open, which breakpoint they were on, or whether the code has changed since. In a component-based app the same button can come from a shared component, a page and a CMS field at once.
Pin vs. context
Where on the page
Screenshot pin: x/y position on an image
Loopa: Route, DOM element and selector on a stored capture
At what size
Screenshot pin: Whatever the reviewer's window was
Loopa: Recorded capture and review viewport
Which code
Screenshot pin: Guessed from visible text
Loopa: Source candidate from a stamp, when the build has one
Which version
Screenshot pin: Unknown
Loopa: Registered build commit, checked against the source index
After a redesign
Screenshot pin: Pin floats over the wrong thing
Loopa: Original capture and anchor stay available
| Question | Screenshot pin | Loopa annotation |
|---|---|---|
| Where on the page | x/y position on an image | Route, DOM element and selector on a stored capture |
| At what size | Whatever the reviewer's window was | Recorded capture and review viewport |
| Which code | Guessed from visible text | Source candidate from a stamp, when the build has one |
| Which version | Unknown | Registered build commit, checked against the source index |
| After a redesign | Pin floats over the wrong thing | Original capture and anchor stay available |
Source candidates
Connecting rendered elements to source code
Loopa does not guess files from class names or visible text alone. Source context is evidence recorded at capture time from your own build, so it can be checked against the commit you are about to change.
Your build stamps rendered elements
Source stamps are attributes such as
data-insp-path="app/pricing/page.tsx:22:7"that record which JSX/TSX location rendered each host element. They come from a build-time transform in your Next.js app.Your build serves a source index
A small JSON index served alongside the build lists the stamped files and the git commit they were built from.
Capture records the evidence
When Loopa captures a route, it reads the stamps and the index, and checks the index commit against the build you registered for the capture.
Annotations get candidates
When you select an element, Loopa looks for a stamp on it or on its nearest stamped ancestor and stores the result as a candidate, with how it was found.
From stamps to candidates
Side by side
The rendered element and its source candidate
Select a button on the captured page; the inspector shows where it was rendered and, separately, where its text came from.
export function PlanCard({ plan }: PlanCardProps) { return ( <Card> <CardTitle>{plan.name}</CardTitle> <Button size="lg">{plan.cta}</Button> </Card> );}Side by side
What is recorded
Source information on an annotation
Each field says where it came from. Page metadata is treated as untrusted input, so an agent can weigh it rather than follow it blindly.
Source context (simplified)
- render location
- components/pricing/plan-card.tsx:35:7From a source stamp; relation self or ancestor
- content origin
- Candidate file for the visible text, when the index has a unique matchUnknown or ambiguous otherwise
- build
- Registered commit SHA, and whether it was built clean
- index state
- loaded, no stamps, missing, invalid, unregistered, dirty or mismatched build
- provenance
- Captured stamp, untrusted page metadata
- visual context
- Route, element, selector, viewport and screenshot: always present
Confidence and fallbacks
When the evidence is unclear, Loopa says so
A wrong file is worse than no file: it sends a person or an agent to the wrong place with confidence. Loopa keeps the three cases apart.
Stamp found on the element or an ancestor
The file, line and column are stored with their relation (self or ancestor) and the matching build. Strong evidence, still labelled as a candidate.
Several plausible origins
Visible text that matches more than one indexed file is marked ambiguous instead of picking one. Where an element was rendered and where its text came from are kept as separate fields.
No usable source evidence
No stamps, no index, an index for a different build, or a build with uncommitted changes. The reason is recorded and the annotation keeps its full visual context.
Candidate, ambiguous, unknown
With coding agents
Less searching, fewer confident guesses
An agent that knows the candidate file and the build can start in the right place and confirm it against the checkout. When there is no candidate, it knows to search instead of assuming.
What your agent receivesStarts in the right file
Candidates point at the component and line, not a whole repository.
Knows the base
The batch names the repository and commit the feedback was given on.
Sees the uncertainty
Ambiguous and unknown states come through as data.
Keeps visual intent
Screenshot and element context travel with every item.
Set up source-aware review
Register your build, capture a route and see which annotations get source candidates.