Opens this plan in Hirezen, where one click makes it a position.
Frontend Developer interview questionsSystem design — comments strangers write on product pages round
A 60 min interview plan with a time-boxed script, what each question is for, and the signals to score against. Key skills: Frontend system design for comments users write: rendering markdown from strangers without cross-site scripting, keeping optimistic posts and live updates from duplicating or reverting, and loading thousands of comments without slowing the product page on phones..
What a comment can do
What this section is for
Purpose
Runs over a two-page design doc for comments on product pages, written as if by a colleague and sent the day before. The requirements: shoppers comment under a product in markdown — bold, lists, links and images; staff replies carry a badge; new comments appear live for everyone viewing the product; the most-discussed products have about 3,000 comments. The draft design, with its plants: markdown is turned into HTML on the client by a renderer configured to pass raw HTML through and to leave link URLs as written, cleaned by `stripScripts()`, an existing helper that removes `<script>` elements with a regular expression, and inserted with `dangerouslySetInnerHTML`; images in comments load from whatever URL the author gave, with no dimensions; the product page fetches every comment with `limit=all` after hydration and renders them in the same tree as the product details, and the renderer adds 38 KB of compressed JavaScript to the product page's main bundle; a WebSocket opens on every product view, and `comment.created` events are inserted at the top of the list; posting is optimistic, with the new comment added under a temporary id and replaced by the server's copy when the POST returns, and a failed POST retried once after five seconds; an edit sends a PATCH, and everyone receives `comment.updated` carrying the new text and no version, applied as it arrives; the API runs on several instances that publish events through a shared broker; and on reconnect the client resubscribes and does nothing else. What is right: the server stores raw markdown rather than HTML, and the API already offers cursor pagination at 20 comments a page, which the draft does not use. Leave one review comment on the doc as a red herring: "links need rel=noopener or this is a tabnabbing hole". The draft assumes a React front end; nothing in the round depends on it. Book 70 minutes; the candidate's questions are on top of the 60.
I'm [YOUR_NAME], and I work on product pages at [COMPANY_NAME]. A colleague wrote this design for comments and asked for a review before anyone builds it. Review it with me, and whenever you would rather redesign a part than comment on it, go ahead.
What this section is for
Purpose
Makes the candidate a reviewer with licence to redesign, so the hour produces decisions rather than a list of concerns.
Start with rendering. Everything inside a comment was typed by someone we know nothing about.
What this section is for
Purpose
Points at the rendering path first, because it is the part of the doc that can hurt shoppers who never read a comment.
Take the rendering path as the draft describes it. What can a comment do to this page today, and what would you build instead?
What this question is for, and what to listen for
Purpose
Reads browser security from a payload rather than from vocabulary. The draft has two holes a working frontend developer finds in minutes, and one red herring a reviewer has already left on the doc.
Signals to score
- Writes a comment that runs code on the page — an image whose error handler runs script, or a markdown link whose URL uses the `javascript:` scheme — rather than saying "XSS" in the abstract
- Explains why `stripScripts()` cannot work: removing `<script>` elements leaves event-handler attributes and dangerous URLs, and a regular expression does not parse HTML the way a browser does
- Says what the script can do with an HttpOnly session: send requests as the signed-in shopper on the shop's own origin — read their account, change their saved address, fill their cart
- Keeps raw HTML out of the markdown output and runs a maintained allow-list sanitiser as the last step before insertion, or renders markdown straight into elements with no HTML string at all
- Allow-lists URL schemes for links and images, and says escaping text does nothing for what a URL does
- Sanitises at render, and says why that is safer than sanitising only at save
- Adds a Content Security Policy with nonces and no `unsafe-inline` as defence in depth, and says what it would and would not have stopped
- Deals with images from arbitrary URLs — each view tells a stranger the shopper's IP address — by proxying them or allowing only uploads
- Knows browsers already treat `target="_blank"` as `noopener`, and does not spend the review on the comment about it
- Would try the payloads against staging before and after the change
Follow-up questions
- Write me a comment that runs code on this page with the draft as it is.
- `stripScripts()` removes every `<script>`. What does it leave?
- The session cookie is HttpOnly. What can the script still do?
- The review comment on the doc says links need `rel="noopener"`. Is that the hole?
- Where does sanitising happen in your design — when the comment is saved, when it is rendered, or both?
Posting while others post
What this section is for
Purpose
Keep the draft's sequence in front of the candidate: temporary id, POST, `comment.created` to everyone, a retry after five seconds, `comment.updated` with no version, resubscribe on reconnect. If they start redesigning before they have traced what the draft does, ask them to run the draft first.
Now the live part. Someone posts a comment while forty other people are looking at the same product.
What this section is for
Purpose
Sets concurrency up as ordinary traffic rather than as an edge case.
Walk me through what the person posting sees, and what everyone else sees, when a comment is posted and then edited twice in quick succession — first with the draft, then with your design.
What this question is for, and what to listen for
Purpose
Reads async UI state in a design rather than in code: three sources of truth about one comment — the optimistic write, the response, the live event — and whether the candidate gives them one identity and one order.
Signals to score
- Finds the duplicate in the draft: the poster's own `comment.created` can arrive before the POST response, so the temporary comment and the server's copy both show, and then two entries share one id
- Gives each comment an id chosen by the client before sending, kept by the server and echoed in the event, so the optimistic copy, the response and the event are recognisably one comment
- Makes the retry safe: the same id sent twice creates one comment, not two
- Says what the poster sees while sending and after a failure, and lets them retry without retyping
- Gives each comment a version from the server and drops an event older than what is on screen, instead of applying events in arrival order
- Stops the echo of the poster's own edit from flashing the text they just replaced
- Covers reconnecting: what was missed while the socket was down, and how the list catches up through the same path without duplicates
- Decides what happens to new comments from others while someone is reading — inserted at once or held behind a "new comments" control — and says why
- Keeps comment state in one place that all three sources update, rather than three code paths that each append
Follow-up questions
- The WebSocket is quicker than the POST response for the person posting. What do they see?
- The POST times out and the client retries after five seconds. How many comments exist now?
- Two edits, seconds apart, are handled by different API instances, and their events arrive in the wrong order. What is on screen?
- A phone loses its connection for forty seconds in a lift. What happens when it comes back?
- Someone is reading the twelfth comment when three new ones arrive. What happens on their screen?
The page that sells
What this section is for
Purpose
The feature's cost to everyone who never uses it. Keep the numbers in view: a 38 KB renderer in the main bundle, `limit=all` against an API that paginates, up to 3,000 comments, a socket per product view, and images without dimensions.
Last part. Most shoppers never scroll as far as the comments, and the product page is the page that sells.
What this section is for
Purpose
Names who the design has to protect before the question is asked, so the answer is about them rather than about a list component.
Tell me how this feature loads so that the product page is no slower on a phone for the shoppers who never read a comment — and how you would know after launch.
What this question is for, and what to listen for
Purpose
Reads web performance for something not yet built: whether the candidate protects the page the feature sits on, and sets a bar in the field before shipping rather than after.
Signals to score
- Starts from what the draft costs a shopper who never scrolls to the comments — bundle, fetch, render and a socket on every product view
- Takes the markdown renderer out of the product page's main bundle — loaded with the section, or run on the server so the client ships none of it
- Loads the section when it nears the viewport and uses the API's cursor pagination — a first page, then "Show more" — instead of `limit=all`
- Decides whether the first page of comments is rendered on the server or fetched by the client, with reasons in terms of what gets indexed, what can be cached and what has to hydrate
- Keeps comments mostly static HTML, with interactivity only where a shopper replies or edits, rather than thousands of hydrated components
- Reserves space for images in comments — dimensions stored at upload, or a fixed box — because images arriving during a scroll shift the page
- Opens the live connection only when the section is visible, and closes it when the tab is hidden
- Sets the bar in field terms — no regression in the product page's p75 LCP, INP and CLS on phones — and watches it by release, behind a flag that can switch the feature off
- Says what the first release leaves out
Follow-up questions
- The draft fetches every comment with `limit=all` after hydration. What does that cost a shopper who never scrolls?
- Where does the 38 KB renderer end up in your design?
- A comment contains a photo with no dimensions. What happens as someone scrolls past it?
- Would you render the first comments on the server? What does that do to caching the product page?
- After launch, how do you know product pages did not get slower on phones?
That's the design review. What would you like to ask about how a feature like this would ship here? [Say plainly how user-written content is rendered on your site today, and whether anyone has tried to break it.]
What this section is for
Purpose
A candidate who takes untrusted content seriously will ask about it. The honest answer to the bracketed question is also the most useful thing they can learn about the job from this round.
Frontend Developer interviews — common questions
- Who is this Frontend Developer interview plan for?
- It is written for the interviewer, not the candidate: the hiring manager, engineer or panel member running the System design — comments strangers write on product pages round for a Frontend Developer role. It gives you a 60 min script to follow in the conversation — 3 questions with what each one is for and the signals to score against — so you are not writing the round from scratch the night before.
- What does the System design — comments strangers write on product pages round assess?
- This round is focused on: Frontend system design for comments users write: rendering markdown from strangers without cross-site scripting, keeping optimistic posts and live updates from duplicating or reverting, and loading thousands of comments without slowing the product page on phones.. It works through What a comment can do, Posting while others post and The page that sells, scoring against 28 observable signals, with follow-up prompts on all 3 questions for going deeper where an answer is thin.
- How is the 60 min split up?
- What a comment can do (18 min), Posting while others post (20 min), The page that sells (22 min). The timings are there so the round stays on schedule and every candidate gets the same shape of interview — which is what makes two candidates comparable afterwards.
- What other rounds should I run for a Frontend Developer?
A single round does not cover a whole role. The other rounds in this library for a Frontend Developer: