References to files are parsed statically. We use static analysis to determine which files a notebook uses so that we can automatically publish referenced files when a notebook is published (and only referenced files), and similarly copy only referenced files when forking a notebook. The FileAttachment function thus accepts only literal strings; code such as
FileAttachment("my" + "file.csv")
or similar dynamic invocation is invalid syntax. For details on how this is implemented, see our parser.
If you want to just swap different images dynamically, maybe you can pull all the .url() to another cell in an object like {a:…,b:…,c…} and then use that to get the image dynamically from the list of uploaded files? I’m sure it has an overhead of waiting for the urls though.
Mike is spilling aLL Ze SeCrEts if you just watch the Observable repos long enough, e.g. observablehq/parser/pull/129.
On a more serious note, it’s easier to explain Observable (and its gotchas) to others if you understand how it works under the hood. And, except for the occasional dependabot rampage, they’re not too noisy.
We use static analysis to determine which files your notebook references, so that files are automatically made public when you publish. There are ways to circumvent this, but it shouldn’t be needed if you enumerate your file attachments statically as shown above. And it’s also important to note that this technique is compatible with lazy loading: a referenced file is not loaded until you call a load method on it, such as file.image or file.json.