When a page and its parent layout both declare the same head entry, which declaration reaches the document?
answer
- depth beats breadth
- child over parent for the same key
- no key to match means both are emitted
- omitting inherits; an empty value removes
basics
~20 sThe deeper declaration usually wins for an entry the framework can identify by key, while entries it cannot tell apart accumulate and both appear. Frameworks differ on whether a nested group is replaced wholesale or merged field by field.
solid answer
~50 sMerging runs from the root down the matched chain, and the rule turns on whether the framework can *identify* two declarations as the same entry. Entries with a natural identity — the title, a named `meta` entry, a `link` with a given relation — are keyed, and the deepest segment declaring that key wins; the parent's value is simply not emitted. Entries with no distinguishing key are appended, which is why the same `link` declared at two levels can appear twice. Two wrinkles matter: a parent often declares a *title pattern* that wraps whatever a descendant supplies, and a child usually needs an explicit empty value to *remove* something a parent set — omitting it inherits. Frameworks also differ on nested groups, such as a block of preview entries: some replace the whole group when a child declares any part of it, others merge field by field.
go deeper
Recall the direction: declarations flow from the root down, and the segment closest to the page wins when both describe the same entry.
Explain the identity rule — keyed entries collapse to the deepest declaration, unkeyed list entries are appended — and how a child clears a value an ancestor set.
Expect the duplicate-tag and half-replaced-group failures in real output, and verify the merged head in the served response rather than trusting the declarations.
Set the convention for which level owns which entries, so pages do not each restate site-wide values and the merge is rarely asked to arbitrate at all.
## Two declarations, one head A URL is served by a chain of segments, each of which may declare head entries, and the document gets exactly one `<head>`. So the framework needs a rule for the moment two segments in the chain describe the same thing. Interviews ask for that rule because getting it wrong produces output that looks plausible in a browser and is duplicated, missing or half-overwritten in the bytes a machine consumer reads. ## The rule turns on identity Split the entries into two kinds: - **Keyed entries** have a natural identity the framework can compare: the title, a `meta` entry with a given name, a `link` with a particular relation. Two declarations of the same key are recognised as being about the same thing. - **Unkeyed list entries** carry nothing the framework can match on. It has no basis for deciding that two of them are the same entry, so it appends both. For a keyed entry the merge runs root-first and **the deepest declaration wins**: the ancestor's value is not emitted at all, it is replaced. For an unkeyed entry, both survive into the output. | case | parent declares | child declares | what is emitted | |---|---|---|---| | keyed entry re-declared | a title | a title | the child's title | | entry only the parent declares | a description | nothing | the parent's description | | unkeyed list entry | a `link` | the same `link` | both, twice | | explicit clear | a description | the same key, empty | nothing | | nested group, replace semantics | a group of preview entries | one field of that group | only the child's field | | nested group, merge semantics | a group of preview entries | one field of that group | the parent's group with that field replaced | The last two rows are the honest answer to "what happens to a nested group": **meta-frameworks differ here**. Some treat a group as a single keyed value and replace it wholesale as soon as a child declares any part of it; others merge it field by field. Saying that the difference exists, and that you would confirm which behaviour applies by reading the served head, is a stronger answer than asserting one of them. ## Omission is inheritance; removal is explicit The most common surprise is that leaving an entry out does **not** suppress it. A child that declares nothing about the description inherits the ancestor's description — which is usually what you want, and occasionally not. Removing an ancestor's entry takes an explicit declaration of the same key with an empty or null value, or whatever clearing marker the framework exposes. Where neither exists, the only remedy is to move the declaration down so the ancestor never sets it for this branch at all. ## Patterns and suffixes Titles are special enough that most frameworks give them a second mechanism: a parent declares a **pattern** — a template with a placeholder for the descendant's part — and each page supplies only its own fragment. The merge then produces the composed string. Two things follow. First, the pattern belongs at the highest level that owns the suffix, typically the root shell or a section layout, so pages never restate it. Second, a page that must escape the pattern needs a way to declare an **absolute** title, and frameworks that support patterns generally provide one. ## Where this goes wrong in practice - **Duplicate tags.** A relation declared in both a layout and its pages, with nothing to key on, is emitted twice. Consumers vary in how they handle a repeated entry, and none of them should have to. - **Half-replaced groups.** A child declares one field of a preview group under replace semantics, and everything else in that group silently disappears. - **Defaults restated everywhere.** Every page re-declaring the site-wide values means the merge never has to arbitrate — and also that changing a default is a change to every page. - **Clearing by omission.** A page that wants no description omits it and inherits one. - **Verifying in the wrong place.** The declaration is not the output. Read the merged head in the served response. ## What to say in an interview State the direction first — declarations flow root-down, the segment nearest the page wins a keyed entry — then add the two refinements that show you have actually shipped this: unkeyed entries accumulate rather than override, and omitting an entry inherits it while an explicit empty value removes it. Finish with the honest caveat about nested groups differing between frameworks, and with how you would check: fetch the URL and read the head that was actually emitted.
- How does a child stop a parent's entry from appearing at all?By declaring the same key with an explicit empty or null value, which the merge treats as a removal. Leaving the key out is inheritance, not removal — the parent's value survives. Some frameworks expose an explicit clearing marker instead; where neither exists, the declaration has to move down the chain.
- Why does the same link relation sometimes appear twice in the output?Because the merge could not tell the two declarations apart. Keyed entries collapse to one; a list entry with nothing to match on is appended, so a parent and a child each declaring it yield two tags. Give such entries an explicit identifier where the framework supports one, or declare them at a single level.
- What is a title pattern, and where should it live?A parent-level template with a placeholder for a descendant's title, so pages supply only their own part and the suffix is written once. It belongs at the highest level that owns that suffix — usually the root shell or a section layout — and a page that must escape it declares an absolute title instead.
A company handbook sets the dress code and a team memo restates one line of it — for that line the memo wins, because everyone can see the two notices are about the same rule. A memo that merely adds 'bring a badge' replaces nothing, and both notices stand.
saying these in an interview costs you the question
- Believes a parent layout's entry overrides the child's.
- Assumes declarations always add up and never replace.
- Expects nested entry groups to merge field by field in every framework.
- Omits an entry expecting that to erase the parent's value.
- Treats duplicated tags in the output as always harmless.
- Judges the result from the declarations rather than the served head.