I am using family recipes to teach myself Typst. With help from many of you, it is going well, but I’ve just hit another problem that I don’t know how to solve. I have created a test version of part of it, where the problem occurs, which can be accessed, I hope at Typst.
The problem is that the anchor of the footnote at the bottom of page 2 occurs in the first paragraph on page 3.
In the code of that project there are two versions of Heading 2
. As it stands, the version which is active is the one I have created following exchanges in other threads to avoid the problem of having a Heading 2
as a widow at the bottom of a page — what in a word processor I would solve with “Keep with Next”. As I couldn’t find any “Keep with Next” coding examples, I used the “conditional upon available space” option.
#show heading.where(level: 2): it => {
set text(18pt, weight: "semibold")
let threshold = 6em
block(breakable: false, height: threshold)
v(-threshold, weak: true)
it
}
// #show heading.where(level: 2): set text(18pt, weight: "semibold")
While that code solves the heading problem, the result is that in the redrawing of the pages, the footnote remains on page 2 but the text with the anchor is moved to page three.
If you comment out the conditional code and re-instate the simple text size and weight assignment code, the footnote and its anchor are both on page two, but there is an ugly end of page 1 and widowed Heading 2
s elsewhere in the full project.
Any help with solving this will be most welcome — and do feel free to try any of the recipes!

Mark
Hello @Mark_Hilton , this looks very yummy 
There is a lot of code in your example that does not relate to the problem you are encountering, making it harder for others to try to help you quickly. A MWE would greatly augment the chances of receiving some help.
However, it seems you have correctly identified the culprit (the level 2 heading
). If you remove the code, the footnote
shows up properly after being declared.
#set page(paper: "a8")
// Culprit
#show heading.where(level: 2): it => {
let threshold = 6em
block(breakable: false, height: threshold)
v(-threshold, weak: true)
it
}
= L1
== Short Footnote (ok)
#lorem(1)#footnote[#lorem(20)]#lorem(1)
= L1
== Long Footnote (not ok)
#lorem(1)#footnote[#lorem(25)]#lorem(1)
The issue you are experiencing is very similar has similarities to with the one here (note the use of a MWE by OP) How do I avoid splitting footnote on multiple pages? - #2 by PgBiel. However, the fix mentioned by @PgBiel in that case doesn’t seem to work, or at least comes in conflict with your heading
level 2 show
rule:
// At the TOP of your document:
#show footnote.entry: block.with(breakable: false)
I guess you can’t push on both sides at the same time. Someone else may have more insight on the internals of Typst about that.
One solution, as you can see in my MWE, is to reduce the length of the footnote…I had yours fit on the page at 112 characters. I understand this may not be what you are looking for.
Another solution would be to amend that heading
level 2 show
rule. Are you willing to have two recipes on the same page? Perhaps a pagebreak()
after each level 2 heading
would be in order?
Edit: There is an open issue about this: Footnote precedes a reference to it · Issue #5314 · typst/typst · GitHub
Thanks for getting back to me so quickly.
Firstly, I’m sorry not to have created an MWE; I gave it considerable thought, but as the issue involved three full pages and replacing any of the text with something shorter would have altered everything. To start from scratch to reproduce it would have taken me more time than I had available, while giving access to the actual pages would be quicker for me and clearly illustrate the problem. Next time, I’ll be more diligent about creating an MWE.
I read the other thread you mentioned and @PgBiel’s solution, but it seemed a different case and the solution didn’t appear relevant (where I could understand it). As for editing the footnote to shorten it to resolve the problem… that seems a rather retrogressive step to me—editing the text to suit page-layout constraints was the sort of thing one did using a WYSIWYG word processor—and something I want to get away from.
For your other solution, there are already cases where there are two recipes on one page. I don’t think a pagebreak()
after a level 2 heading would solve it as that would separate the heading from what follows, exactly the opposite of “Keep with Next”. I have considered a pagebreak()
before a level 1 heading, which would effectively mean every recipe starting on a new page, but have rejected that as creating far too much wasted space over the whole collection—I have only done about a quarter of the recipes so far and it’s already ca 50 pages long; with each recipe starting on a new page it would be more in the region of 70 pages.
I have read the issue on GitHub. I must sign up to GitHub to be able to participate there, which I’ll do when I have the time. Let’s hope that they will get round to implementing a solution to this.

Mark
Thanks for your reply Mark,
I hear you. Just to illustrate to you how I came this quick with a MRE for your case and to help you achieve the same should you need in the future:
- I took your code, removed any text and replaced it by generated text with the
lorem(30)
function. This greatly reduces the size of the code to look at and helps focusing on the real issue.
- I then removed each section of code that I thought was irrelevant to the case, ensuring each time id did not solve the issue.
- I posted what was left (which is the MRE). Sometimes it is easy to create one from scratch, sometimes (like in your case), it is not quite evident to do. Well done again for identifying the culprit early though.
- I changed the page size to make it easier to see it and added a case where the footnote did not break but that was an unnecessary step.
For the rest, as you see, I could only point to what solutions/posts had a resemblance with your case, hence my struck text and comments. I appreciate none of this is a final solution.
I did find the the GitHub issue a bit later. It is definitely worth following, at least you now know you need a workaround if you want to manually achieve the desired result.
P.S. I’m actually glad for the recipes which would have been gone should you have posted a MRE 
Thanks for that, especially how you created your MRE.
Until some solution to this bug is found—and preferably built into Typst—I have decided that the best workaround for me at the moment is
- to leave level 2 headings simple and manually put pagebreaks where needed, even though that means having to check each “chapter” as I add recipes towards the beginning for knock-on effects.
- to make level 3 headings conditional to solve similar situations at that level, again checking for any similar effects…
I have also decided to explore the “Marginalia” package, to use margin notes rather than footnotes to see how that works.
Glad you find the recipes interesting; I did think before my original posting, that by giving a link rather than spending time on an MWE, that it would also pass on the recipes to anyone who was interested. Of the three, we make “Merluza alla Gallega” very often; it’s delicious.

Mark
1 Like