 This is my favorite, it's the only reason I do this series. So it's for this bit. That's why I get really like, if it's not happening, I'm like, whoa, whoa, whoa, whoa. On the face massage. Face massage? Yes. You call it what you want, I'll call it what I want. A gentle brow stroke. I'm happy. We built a thing. Did we? We built a thing. Have we ever talked about this thing? We talked about nothing but. And this is it. This is. It's both of us. Image compression, web app thing, all runs on the web. As you can see, image has gone from two point. Whatever makes it. It's great. Anyway, check it out if you have. Whatever, whatever. But, but, what I wanted to talk about is share target. All right. All right, so. So share target is already a thing. It's been already shipped and it's in stable, right? Parts of it have and parts of it haven't. Oh, it's part. I'm going to go through both of them. All right, cool. So, here's what it does. Oh, look at our stupid faces. Here's our stupid faces. This is Google Photos. This is the native app. Yeah. On Android. I'm going to hit share. And I'm going to share to. There's a Squoosh. Squoosh. And the image opens. And this is just a web app. So we just shared from a native app to a web app. To a web app. That's pretty cool. And even it's an entire image and things. Yes, and it works. And it feels like a real native experience. So now I can actually, I mean, this is the workflow that we have been missing, right? Because you want to compress your image. How do you get your image from photos into a Squoosh? You have to open a Squoosh, say load an image, select the photos app, then you get the select of all the images. And now you go image, flunk. Yes, and so anything that can share images. It's the official sound, isn't it? Flunk. Yeah, well, it means you could do that from Twitter. From anything that will actually share an image, you could then take it straight into Squoosh. So is that only for, it's a manifest thing, I presume? This is one of the few PWA-only features that we have. The MewMean only once it's installed, it will actually work. Exactly. So visiting the page, like if I visit a Squoosh in my browser, it will not register as a share target. It will not register as a share target. Cool. The way you do it, like you say, is in the web at manifest. So you see all these things. OK. Name, style URL, that's all the usual stuff. But then, ooh. Share target. Share targets. OK. And then an action. Now, this is action in the same way form action works. So because what share target is going to do, the way it's going to share the things is it's going to make a form submission. So like a post request. Well, you get to specify the method. And this works the same. All right, in the form, you do that as well, actually. Now, they say that. I haven't done form in ages. Now they say that. But yeah. Yeah, well, this is it. It does exactly the same as like a form. Method does. And you can specify the encoding type, which is the same. So we spell out share target, but in coding time, we shorten it to nctype. Because that's the attribute on the form element. I didn't even know that existed. Yeah, yeah, this is the thing. If you have a file input in a form, you have to set the nctype to multi-part form data. Because that's the only form encoding that supports files. OK. This format doesn't. The nctype only matters if you're a post method. So x doesn't form your own code. It means all the things in my form, whatever it is, will be appended to the action URL as query parameters. Well, that depends on what method it is. If it's post, it will be sent as the post body. If it's get, you're right. It's going to end up at the end of the URL. And then you specify these parameters. So quick, quick corner, because I'm curious. If I already have some query parameters in my action URL, will it successfully merge? Yes, it will. Yeah. OK, cool. I imagine not tested it, but that's what form does. OK, cool. We would expect the same thing here. So in here, the things the operating system may give you as part of a share is the title, the text, the URL. So this is the classic text share or link share kind of thing. Yep. And I'm mapping it to the form field names that I'm interested in. So and if I remember correctly, that is the part that is already shipped and stable. This is shipped and stable. This has been in since 71 on Android. So I've built a web app that uses this. OK, show me your work, your glorious. What this does, this is the text share target app. And what it does, it tells you what the URL is. That's very good. Look, it's a good app. And what I'm going to do is we're going to install the home screen because it's that good. Because it's that good. I use it all the time. I'm going to go into the YouTube native app. I'm going to go into look at these jokers. And I'm going to share. And I can share to that app. All right. And if I share, there you go. So the URL is, it's got all that stuff on. And if it, you know, break it apart here, the share title is now watch context and optimizations on YouTube. And you should. And the share text, which is the URL. Now, it's a bit weird that the text is the URL when there's a URL for it. Yeah. I hate that because you know how when you sometimes share from the Twitter app to like WhatsApp or something. Yes. Read this tweet from like, no. And that is going to pick up that horrible text. And you're really going to receive whatever the native app has given you. And so you kind of have to deal with that, which is sad. That being said, this is pretty cool. Like I can share, be a share target for link sharing and stuff. Yeah. And if I go into photos now, like I did before, I can do the same thing, share to the text, share target. It's going to ask me if I want to create a link or a shared album. Because it's only a text share target. Because it is just a text share target. And the share text that comes out is a link to it. And there's no time saying, check out this image from Jake Archibald. Well, yeah, so this is better than what we had before. But in version two of share target, you can share files. Hey. Did you see that going? Brilliant. You always showed me, mate. Yeah, I did sort of destroy the surprise in the first couple of seconds of the video, didn't I? Fair enough. Good storyteller right there. So, slightly different. Back again in the manifest, action, same. Method post this time. Because if you're going to receive files, it has to be a post. The encoding type is multi-part form data. It has to be that if you want files. And you can still put the usual parameters in. But there's this new one, which is files. And you have an array. So the mere existence, it has to be post and files. It basically make your file target, or it's files. If you have get in there, it will throw a warning into the console and say, yeah. That doesn't make sense. No, it just says that. You have to work out the rest yourself. The play button, please. So here I'm saying files. And this is the mapping again. I'm saying the name of the form field is file. I can call that whatever I want. Oh, and it can filter by MIME type. That's good. And you can filter by MIME type. If you just want to have images, you can say image slash star, I presume. Yeah, which is actually, we had this problem in Squoosh, where, because we've made it so you can load WebP in browsers that don't support WebP. But if you try and filter by MIME type, the browser goes, I don't understand what WebP is. This is not an image. So we had to sort of do this same hack, even though we're wanting to receive images. We had to say, we'll accept anything because we will take file formats the operating system browser doesn't understand. Makes sense, yeah. OK. So yeah, that's that. So you say this gives me a post request, right? So that is not as easy to handle as a get request with parameters. Yes. I mean, by default, this will just go to your server, and your server handles it. True. Which might be OK in some cases. But for Squoosh, we want it to work offline. So we don't want this to actually go to the server. We don't want it to depend on the server. There is no server. We are serverless. We're serverless. Another buzzword that we encompass. So in order to solve this, service worker. So the service worker we go. Yes. So now this is, I think this will be the first time. No, the second. No, the first time I handling a post request in my service worker, I think. Yeah? Yeah, although I think maybe in log press when you post a comment, I did it. Maybe. I've done it before to trap post request that didn't work and save them for later. That's all the background sync. Yeah. Background sync. But in this case, what I'm going to do, look at the URL, and if it's the same origin request, and if it's to the share target, this is all what we set up in the manifest. And if it's a post thing, we're going to do something else. We're going to do something magic. It's not magic. The rest stays the same, but yeah. Yes, so you would still have the rest of your service worker logic there. We're just catching this one case. And what we're going to do, we're going to respond with a redirect. OK. And this is basically what you would do on the server side. Yeah, I think you basically never respond to a post request with content. You would say no content or a redirect. You would sometimes respond with a content if it was an error in the post. You would serve back the form with all the data, but one field saying this one's wrong. But if stuff is correct, you tend to serve a redirect. And that's because, I don't know, you might have seen this where you hit refresh on a page and it says, do you want to resubmit? Exactly. And that's because this page was a post response, or a response to a post request. So you serve a redirect. That makes it a get request. And the user can hit refresh, and it's not a problem. So with the redirect, the body will still get forward? That will make the browser do a get request after, right? So you will have to read the body on a post request and then pass it along to the get request somehow? To the page. Well, no, we can pass it along just to the page. There are redirect codes that say you should, if this was a post request, you should do a post request again with the same data. But the default redirect stuff doesn't do that. So basically, what you're doing is you're ripping out the body from the post requests. Meanwhile, you're redirecting the client, which will send a get request, hit your normal service worker path, hit the cache, load the page. Great. That's an important detail, actually, a redirect. It will send it back through the service worker. So now the page is up? Well, the page is not up yet. Because at the same time, we are going to, as you say, we're going to get that form data, which is what the share target is giving us. And it's going to give us that file. We're going to do this. And this is relative claims. So I know clients exists. It's like all the clients, the tabs, if you want to say. And workers. And workers. Simply said, that belong to the service worker, right? Or that are handled by the service worker. Yes, the ones that are controlled. You can actually get all of the ones for the origin as well. So I've never used it. I know it exists. But this would be the first time I have seen a use case for it. And this is quite a new bit here, this resulting client ID. And what it's saying is like, there's not a page yet. But here's an ID for it for whenever it appears. And so when I clients.get it, it's going to wait until that page appears. So that will be the page that you have spawned by the redirect? Yes. Well, if I didn't redirect it, it would be the page that you create. Yes, it's the page that results as part of this fetch. So yes, I get the client. And that won't work if the redirect goes to another origin, or it won't work if the page fails to load for that reason. But we're getting the client here because it's going to work. It's our client, so we can have it. Yep. Get the file out of the form data object, using the name that we gave it. So this will incorporate all the multi-part MIME decoding under the hood, giving you an array buffer, a blob, something, a file. You get a file, a file object. Cool. Yep. And now I'm going to post message that to the page. Oh, post message. There it is again. Good old post message. And that means over in my page, I can listen for that message. Why don't you transfer the file? Is it transferable? I probably should transfer it. Ha. So it wins again. Well, here's an interesting thing. I don't know how much it saves if you transfer a file because it's read-only data, right? It's reference on this anywhere. It's not like we saw. It doesn't really make things slow. And it was a pretty big image. We could transfer it. And through doing that, I have another demo. Oh, oh boy. Yeah, yeah. You ready? So it's same as the one before. Same symbol. But it's the file share target. And this is what it says. You can share files to this app. And it's not wrong. You absolutely can. And that is already an achievement for you in the app that you're using. And I will share links to these little demos because they are good minimal cases. And so it is going to appear here. There it is, file share target. And well, look at you even show it. It's like Squoosh. Exactly. Just much simpler. And it just gives you the details, the file, you know, get the name, the size, the mime type. Two megs. That's all in there. And it's sort of two megs or whatever. But this is just a very, like, that's exactly what we're doing with Squoosh. But obviously, we're doing the rest of Squoosh around it. So the result is you can press Squoosh as if it's a native app. And there you go. And you can start editing the image. Hey. And that share target. So this is in Canary right now. Right now? Right now? Right now? I wish we were in Corario out. This is in Canary right now. Yes. It's, they're starting the launch process for it. Fixing a few bugs. So this should land in a few months. This would be a great origin trial, actually. I think they're just going to ship. I think they've got agreement to do that. Exactly. And I think it's great. I think it's one of the huge step towards feeling native. Because if you can actually, you know, I've always thought about my Android workflow as a phone workflow, like you start an app, you do a thing, and you share it to the next app. And you kind of have this chain, like a little bit like a Unix pipe back in the day. And then at the end, you send it via email or whatever. It's actually images. You take an image, then you share it to your photo editor, and you share it to email. Cool. And now you can have your web apps in that chain. Yeah. And that's really big. And it's not just images. It's any kind of files that you want to accept. So there we go. That share target. We'll link to these demos. And we'll link to the articles and stuff and the specs in the thing. Yeah. Let's give it a try. Are we good to go? Absolutely. Amazing. That was fake confidence. Yeah. You've got to remember what I'm doing now. Share target made. All right. Let's do, let's do share target.