-
-
Notifications
You must be signed in to change notification settings - Fork 428
Add template.html transform api #1642
Add template.html transform api #1642
Conversation
5f72674
to
09f8349
Compare
4d44cbb
to
87b3c71
Compare
Ah. VSCode was tricking me by setting my NODE_ENV to "production" in its terminal. Not sure if I did that somehow years ago or what. 🙄 |
ff08180
to
dcb8409
Compare
dcb8409
to
eac4a61
Compare
eac4a61
to
9fb4474
Compare
We're working on a successor to Sapper called SvelteKit and I'd rather any major changes go there given our limited review time. The code for it is still private at the moment while we work on getting things in a more stable state, but hopefully we'll have more to share before too long. |
Yeah, I was hoping that this was simple enough to be included as a feature in both places (while we wait for SvelteKit). If not, I’ll be happy to propose this same thing again if there are no comparable features. |
Oh, and though the documentation here suggests “major” due to the amount of explanation added, the actual amount of effort and change to the code base is pretty small. |
67599a0
to
403589b
Compare
403589b
to
332062c
Compare
@benmccann, here are a few things to consider when comparing the proposed PRs. I've been comparing the proposed solutions and of the three proposals, there are two levels of functionality: coupled to So comparing #1152 and this PR reveals the following differences: This one introduces a new top-level api inside Sapper itself with a function that is used to work with the interface, whereas #1152 hooks into the middleware and provides its new api via the A direct comparison of the same change to the template file PR #1642 version import polka from 'polka';
import * as sapper from '@sapper/server';
import { start } from '../../common.js';
const app = polka()
+ .use((req, res, next) => {
+ if (req.headers['disable-js'] === 'true') {
+ res.replacers = [(body) => body.replace('%sapper.scripts%', '')]
+ }
+ next()
+ })
.use(sapper.middleware())
start(app); This PR version import polka from 'polka';
import * as sapper from '@sapper/server';
import { start } from '../../common.js';
+sapper.registerTemplateTransformer((template, data) =>
+ template
+ .replace(
+ '%sapper.scripts%',
+ () => data.req.headers['disable-js'] === 'true' ? '': '%sapper.scripts%'
+ )
+
+);
const app = polka()
.use(sapper.middleware());
start(app); Of note in the version in this PR, you actually have access to the same data as Sapper itself when doing your replacements. The export type TransformData = Readonly<{
html: any;
head: any;
styles: string;
script: string;
nonce_value: string;
nonce_attr: string;
req: SapperRequest;
}>; And Sapper itself uses that exact same data object to do the default transforms. So you have the ability to make decisions based on what Sapper would be doing as well. Which means I could have just as easily done this in the example above sapper.registerTemplateTransformer((template, data) =>
template
.replace(
'%sapper.scripts%',
- () => data.req.headers['disable-js'] === 'true' ? '': '%sapper.scripts%'
+ () => data.req.headers['disable-js'] === 'true' ? '': data.script
)
); Whether ultimately extending the Finally, one other subtle difference between the two that may honestly never matter: Using the middleware intrinsically ties this feature to the use of the server itself. Though my implementation does work inside |
Thanks! It's helpful to have a comparison between the various PRs. Right now major new features are on hold as we work on SvelteKit. This might be handled differently there, so I'd be hesitant to introduce something that immediately has to change in the new codebase or that users would have to update while migrating. |
Is this still considered for svelte kit? Can't find anything in the milestones or issues about it would be pretty nice to have this feature |
Thanks for this PR!! I don't think we'll be adding anything new to Sapper at this point, but this now exists in SvelteKit! sveltejs/kit#670 |
Before submitting the PR, please make sure you do the following
Tests
npm test
and lint the project withnpm run lint
This api addition to
@sapper/server
allows an escape hatch to arbitrarily transform the contents of thetemplate.html
file as it is being served. In fact, it moves the tag replacements that Sapper already does into this new system.This was done largely to resolve #179, but also resolves #1036: allow access to arbitrarily change the template file as needed. I realize (somewhat after the fact) that there are already two other PRs open that achieve a similar thing (#1037, #1152), but this change allows arbitrary changes to the template (like #1152) and is not tied to adding a new middleware before the Sapper middleware runs.
I know that SvelteKit is on the way, but this change was small enough that I am hoping something similar might be possible there.
Here is the documentation I added so you'll better understand what I have done.
Sapper provides a few tags that it will automatically replace inside the
src/.template.html
file. These replacements can be changed by providing your own template transformer.You can register a template transformer inside the
src/server.js
file.The function that you pass to
registerTemplateTransformer
will be given two arguments:template
: string contents of the template before Sapper's replacementsdata
: an object containing all the values you'd need to completely replace the tags that Sapper itself replaces:html
: stringhead
: stringstyles
: stringscript
: stringnonce_value
: stringnonce_attr
: stringreq
: the request objectYou must return a string which is the full contents of the template file as you'd like them to appear. Any of Sapper's own tags that you do not replace will be replaced as normal by Sapper.
You may call the function multiple times. Transformers will run in the order in which they are registered, with the default Sapper transformer running last.