{"id":346571,"date":"2023-08-31T13:10:12","date_gmt":"2023-08-31T19:10:12","guid":{"rendered":"https:\/\/r-posts.com\/?p=10537"},"modified":"2023-08-31T13:10:12","modified_gmt":"2023-08-31T19:10:12","slug":"build-serverless-shiny-application-via-github-page","status":"publish","type":"post","link":"https:\/\/www.r-bloggers.com\/2023\/08\/build-serverless-shiny-application-via-github-page\/","title":{"rendered":"Build serverless shiny application via Github page"},"content":{"rendered":"<!-- \r\n<div style=\"min-height: 30px;\">\r\n[social4i size=\"small\" align=\"align-left\"]\r\n<\/div>\r\n-->\r\n\r\n<div style=\"border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;\">\r\n[This article was first published on  <strong><a href=\"http:\/\/r-posts.com\/build-serverless-shiny-application-via-github-page\/\"> R-posts.com<\/a><\/strong>, and kindly contributed to <a href=\"https:\/\/www.r-bloggers.com\/\" rel=\"nofollow\">R-bloggers<\/a>].  (You can report issue about the content on this page <a href=\"https:\/\/www.r-bloggers.com\/contact-us\/\">here<\/a>)\r\n<hr>Want to share your content on R-bloggers?<a href=\"https:\/\/www.r-bloggers.com\/add-your-blog\/\" rel=\"nofollow\"> click here<\/a> if you have a blog, or <a href=\"http:\/\/r-posts.com\/\" rel=\"nofollow\"> here<\/a> if you don't.\r\n<\/div>\n<h3 id=\"2f1e\" class=\"pw-subtitle-paragraph tg fj st al b th ti tj tk tl tm tn to tp tq tr ts tt tu tv rj ai\">Simple guide for simple shiny application\u00a0<\/h3>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"tw tx ty tz ua\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"speechify-ignore n di\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"speechify-ignore bm s\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"ub uc ud ue uf n\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n qg\"><\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<h4 id=\"bee1\" class=\"xc xd st al xe xf xg tj lc xh xi tm lh xj xk xl xm xn xo xp xq xr xs xt xu xv bp\">TL;DR<\/h4>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<figure class=\"xx xy xz ya yb yc kd ke paragraph-image\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div role=\"button\" class=\"yd ye by yf bm yg\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"kd ke xw\"><img decoding=\"async\" alt=\"\" class=\"bm yh yi c\" loading=\"lazy\" role=\"presentation\" src=\"https:\/\/i2.wp.com\/miro.medium.com\/v2\/resize:fit:1400\/1*PWtaziBHI4LkX78rzJx--A.png?w=450&#038;ssl=1\" data-recalc-dims=\"1\" \/><\/div>\r\n<\/div>\r\n<\/figure>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<blockquote class=\"yj\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"bd54\" class=\"yk yl st al ym yn yo yp yq yr ys yt ai\" data-selectable-paragraph=\"\">I made<span>\u00a0<\/span><strong class=\"bc\">shiny<\/strong><span>\u00a0<\/span>application in<span>\u00a0<\/span><strong class=\"bc\">github page<\/strong><span>\u00a0<\/span>with<span>\u00a0<\/span><strong class=\"bc\">quarto.<\/strong><\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"c7be\" class=\"yk yl st al ym yn yu yv yw yx yy yt ai\" data-selectable-paragraph=\"\">You can check code in<span>\u00a0<\/span><a class=\"ay yz\" href=\"https:\/\/github.com\/jhk0530\/wasmR\" rel=\"nofollow\" target=\"_blank\">my github repository<\/a><span>\u00a0<\/span>and<span>\u00a0<\/span><a class=\"ay yz\" href=\"https:\/\/jhk0530.github.io\/webR\/\" rel=\"nofollow\" target=\"_blank\">result<\/a>,<span>\u00a0<\/span><a class=\"ay yz\" href=\"https:\/\/jhk0530.github.io\/wasmR\/\" rel=\"nofollow\" target=\"_blank\">result2<\/a><\/p>\r\n<\/blockquote>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<hr \/>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<h4 id=\"42ab\" class=\"xc xd st al xe xf zg tj lc xh zh tm lh xj zi xl xm xn zj xp xq xr zk xt xu xv bp\">How we use shiny<\/h4>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"143f\" class=\"pw-post-body-paragraph zl zm st ly b th zn zo zp tk zq zr zs li zt zu zv ln zw zx zy ls zz aba abb yt ig bp\" data-selectable-paragraph=\"\"><code>Shiny<\/code><span>\u00a0<\/span>is R package to make user utilize R with web browser without install it.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"7030\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">So my company utilizes shiny to provide statistical analysis for doctors (who don\u2019t know R but need statistics).<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<figure class=\"xx xy xz ya yb yc kd ke paragraph-image\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div role=\"button\" class=\"yd ye by yf bm yg\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"kd ke abl\"><img decoding=\"async\" alt=\"\" class=\"bm yh yi c\" loading=\"eager\" role=\"presentation\" src=\"https:\/\/i2.wp.com\/miro.medium.com\/v2\/resize:fit:1400\/1*sasJJ6TfDK4rIdt4JUOpiQ.png?w=450&#038;ssl=1\" data-recalc-dims=\"1\" \/><\/div>\r\n<\/div>\r\n<\/figure>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p za fb jl zb\" role=\"separator\"><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze\"><\/span><\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<hr \/>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<h4 id=\"a5e3\" class=\"xc xd st al xe xf zg tj lc xh zh tm lh xj zi xl xm xn zj xp xq xr zk xt xu xv bp\"><strong class=\"bc\">Behind shiny<\/strong><\/h4>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"64b5\" class=\"pw-post-body-paragraph zl zm st ly b th zn zo zp tk zq zr zs li zt zu zv ln zw zx zy ls zz aba abb yt ig bp\" data-selectable-paragraph=\"\">As you know,<span>\u00a0<\/span><code>shiny<\/code><span>\u00a0<\/span>is consisted with 2 part. UI and Server<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"88ba\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">You may think just<span>\u00a0<\/span><strong class=\"ly gk\">UI<\/strong><span>\u00a0<\/span>is channel to both<span>\u00a0<\/span><strong class=\"ly gk\">get input<\/strong><span>\u00a0<\/span>(data) from user and<span>\u00a0<\/span><strong class=\"ly gk\">return calculated output<\/strong><span>\u00a0<\/span>(result) to user.<br \/>\r\nand<span>\u00a0<\/span><strong class=\"ly gk\">server<\/strong><span>\u00a0<\/span>is just<span>\u00a0<\/span><strong class=\"ly gk\">calculator<\/strong><\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"20eb\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">It means,<span>\u00a0<\/span><strong class=\"ly gk\">server requires<\/strong><span>\u00a0<\/span>dynamic calculation that may<span>\u00a0<\/span><strong class=\"ly gk\">change, not fixed<\/strong><span>\u00a0<\/span>contents (it called as static web page)<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"92ac\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">To achieve dynamic calculation, there are several options.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"71eb\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">We can use<span>\u00a0<\/span><a class=\"ay yz\" href=\"http:\/\/shinyapps.io\/\" rel=\"nofollow\" target=\"_blank\">shinyapps.io<\/a>, posit connect, or deploy own shiny server in other cloud like AWS \/ azure \/ GCP \u2026<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"6627\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">These options can be categorized into two main categories: free but with limited features, or feature-rich but paid.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<figure class=\"xx xy xz ya yb yc kd ke paragraph-image\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div role=\"button\" class=\"yd ye by yf bm yg\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"kd ke abm\"><img decoding=\"async\" alt=\"\" class=\"bm yh yi c\" loading=\"eager\" role=\"presentation\" src=\"https:\/\/i0.wp.com\/miro.medium.com\/v2\/resize:fit:1400\/1*Y1Bmu83mOMum7C2DaWZuZw.png?w=450&#038;ssl=1\" data-recalc-dims=\"1\" \/><\/div>\r\n<\/div>\r\n<\/figure>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"ec5f\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">There is no single right answer, but I use shinyapps.io in see toy level project or deploy using shiny server in company\u2019s cloud server which is not just toy level.<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p za fb jl zb\" role=\"separator\">\r\n\r\n\r\n\r\n\r\n\r\n<hr \/>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p za fb jl zb\" role=\"separator\"><span class=\"zc ch br zd ze zf\"><span style=\"font-size: 20px;font-weight: bold\">The rise of webR<\/span><br \/>\r\n<\/span><\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"4d9b\" class=\"pw-post-body-paragraph zl zm st ly b th zn zo zp tk zq zr zs li zt zu zv ln zw zx zy ls zz aba abb yt ig bp\" data-selectable-paragraph=\"\"><br \/>\r\nRecent,<span>\u00a0<\/span><strong class=\"ly gk\">webassembly<\/strong><span>\u00a0<\/span>(<code>wasm<\/code>) has emerged. that is use programming language in web browser (like Chrome) without install it (via javascript)<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"6b59\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">As far as I know,<span>\u00a0<\/span><a class=\"ay yz\" href=\"https:\/\/webr.r-wasm.org\/\" rel=\"nofollow\" target=\"_blank\">webR<\/a><span>\u00a0<\/span>(R version of wasm) is built from late 2022 and some Examples are being shared to make R available on the web.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"cd5f\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">I understand logic for webR like just below figure. (but understanding is not necessary to run)<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<figure class=\"xx xy xz ya yb yc kd ke paragraph-image\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div role=\"button\" class=\"yd ye by yf bm yg\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"kd ke abn\"><img decoding=\"async\" alt=\"\" class=\"bm yh yi c\" loading=\"eager\" role=\"presentation\" src=\"https:\/\/i0.wp.com\/miro.medium.com\/v2\/resize:fit:1400\/1*O4bp7qWTlXqCxPzDCGLbGw.png?w=450&#038;ssl=1\" data-recalc-dims=\"1\" \/><\/div>\r\n<\/div>\r\n<\/figure>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p za fb jl zb\" role=\"separator\"><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze\"><\/span><\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<hr \/>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<h4 id=\"8fc1\" class=\"xc xd st al xe xf zg tj lc xh zh tm lh xj zi xl xm xn zj xp xq xr zk xt xu xv bp\">Shiny with wasm<\/h4>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"1f2c\" class=\"pw-post-body-paragraph zl zm st ly b th zn zo zp tk zq zr zs li zt zu zv ln zw zx zy ls zz aba abb yt ig bp\" data-selectable-paragraph=\"\">For shiny, there is already wasm application called<span>\u00a0<\/span><a class=\"ay yz\" href=\"https:\/\/shiny.posit.co\/py\/docs\/shinylive.html\" rel=\"nofollow\" target=\"_blank\"><strong class=\"ly gk\">shinylive<\/strong><\/a>. but it utilizes<span>\u00a0<\/span><strong class=\"ly gk\">shiny for Python<\/strong>.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<figure class=\"xx xy xz ya yb yc kd ke paragraph-image\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div role=\"button\" class=\"yd ye by yf bm yg\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"kd ke abo\"><img decoding=\"async\" alt=\"\" class=\"bm yh yi c\" loading=\"eager\" role=\"presentation\" src=\"https:\/\/i0.wp.com\/miro.medium.com\/v2\/resize:fit:1400\/1*P36V4Q29VWbQoFVBA41xvw.png?w=450&#038;ssl=1\" data-recalc-dims=\"1\" \/><\/div>\r\n<\/div>\r\n<\/figure>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"8cd8\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">Personally, I\u2019m not familiar with this. Since I used R for a long time<br \/>\r\nso I wasn\u2019t interested in this.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"db43\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">but very recent, The article has been shared with appsilon\u2019s shiny weekly newsletter.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"7f77\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">and Leemput explains<span>\u00a0<\/span><a class=\"ay yz\" href=\"https:\/\/hypebright.nl\/index.php\/en\/2023\/07\/25\/building-serverless-shiny-apps-with-webr-a-step-by-step-guide\/\" rel=\"nofollow\" target=\"_blank\"><strong class=\"ly gk\">how to implant webR and shiny application in WordPress<\/strong><\/a><span>\u00a0<\/span>very kindly.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"349a\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">Since wordpress provides a static page service, this means that shiny can be planted using the<span>\u00a0<\/span><strong class=\"ly gk\">github page<\/strong><span>\u00a0<\/span>I\u2019m familiar with. (There are examples with netlify. so I think static page service like Vercel, Notion, Firebase or even medium may use webR)<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"4198\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">The logic is just below. (as I understand)<\/p>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<figure class=\"xx xy xz ya yb yc kd ke paragraph-image\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div role=\"button\" class=\"yd ye by yf bm yg\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"kd ke abp\"><img decoding=\"async\" alt=\"\" class=\"bm yh yi c\" loading=\"lazy\" role=\"presentation\" src=\"https:\/\/i1.wp.com\/miro.medium.com\/v2\/resize:fit:1400\/1*vc5QbRL_0ApAApJpCyiTLg.png?w=450&#038;ssl=1\" data-recalc-dims=\"1\" \/><\/div>\r\n<\/div>\r\n<\/figure>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"552c\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">note, Main difference with webR and shiny wasm is service worker<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p za fb jl zb\" role=\"separator\"><span class=\"zc ch br zd ze zf\"><br \/>\r\n<\/span>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<hr \/><\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\"><\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n\r\n\r\n<h4 id=\"9ed7\" class=\"xc xd st al xe xf zg tj lc xh zh tm lh xj zi xl xm xn zj xp xq xr zk xt xu xv bp\">Let\u2019s Build it<\/h4>\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"207e\" class=\"pw-post-body-paragraph zl zm st ly b th zn zo zp tk zq zr zs li zt zu zv ln zw zx zy ls zz aba abb yt ig bp\" data-selectable-paragraph=\"\">To build serverless shiny application with github page, we need 3 + 1 things.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"3008\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">1. HTML contents (<strong class=\"ly gk\">button<\/strong><span>\u00a0<\/span>to show status of wasm and<span>\u00a0<\/span><strong class=\"ly gk\">iframe<\/strong><span>\u00a0<\/span>for shiny applicaiton)<\/p>\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"c55f\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">2. shiny code (<strong class=\"ly gk\">app.R<\/strong>, we\u2019ll utilize pre-made and publicly avaiable app)<\/p>\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"a96a\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">3.<span>\u00a0<\/span><strong class=\"ly gk\">javascript<\/strong><span>\u00a0<\/span>to run service worker (web worker + serivce worker)<\/p>\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"bf4e\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">and hard thing.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"e73a\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">4.<span>\u00a0<\/span><strong class=\"ly gk\">configuration for github page<\/strong><span>\u00a0<\/span>to utilize service worker via proxy.<\/p>\r\n\r\n\r\n\r\n\r\n\r\n<p id=\"aea2\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">we can utilize the resources provided by Leemput. (HTML contents and javascript code)<\/p>\r\n\r\n\r\n\r\n\r\n\r\n<p class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">so let\u2019s make<span>\u00a0<\/span><strong class=\"ly gk\">index.qmd<\/strong><span>\u00a0<\/span>like below (you can check in my<span>\u00a0<\/span><a class=\"ay yz\" href=\"https:\/\/github.com\/jhk0530\/wasmR\/blob\/main\/index.qmd\" rel=\"nofollow\" target=\"_blank\">repo<\/a><span>\u00a0<\/span>too)<br \/>\r\n<br \/>\r\n<strong>Important:<\/strong> Change <strong>html<\/strong> to <strong>\u201c{=html}\u201d<\/strong>. I changed it since it breaks wordpress site.<\/p>\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n<pre>---\r\ntitle: &quot;serverless shiny with github page&quot;\r\ninclude-in-header:\r\ntext: | \r\n  &lt;script&gt; type='application\/javascript' src = 'enable-threads.js' &lt;\/script&gt;\r\n---\r\n\r\n```html\r\n&lt;button class=&quot;btn btn-success btn-sm&quot; type=&quot;button&quot; style=&quot;background-color: dodgerblue&quot; id=&quot;statusButton&quot;&gt;\r\n  &lt;i class=&quot;fas fa-spinner fa-spin&quot;&gt;&lt;\/i&gt;\r\n  Loading webR...\r\n&lt;\/button&gt;\r\n&lt;div id=&quot;iframeContainer&quot;&gt;&lt;\/div&gt;\r\n&lt;script defer src=&quot;&lt;https:\/\/use.fontawesome.com\/releases\/v5.15.4\/js\/all.js&gt;&quot; integrity=&quot;sha384-rOA1PnstxnOBLzCLMcre8ybwbTmemjzdNlILg8O7z1lUkLXozs4DHonlDtnE7fpc&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;\/script&gt;\r\n&lt;script type=&quot;module&quot;&gt;\r\n  import { WebR } from '&lt;https:\/\/webr.r-wasm.org\/latest\/webr.mjs&gt;';\r\n  const webR = new WebR();\r\n  \/\/ TODO\r\n  const shinyScriptURL = '&lt;https:\/\/raw.githubusercontent.com\/rstudio\/shiny\/main\/inst\/examples\/01_hello\/app.R&gt;'\r\n  const shinyScriptName = 'app.R'\r\n  let webSocketHandleCounter = 0;\r\n  let webSocketRefs = {};\r\n  const loadShiny = async () =&gt; {\r\n    try {\r\n      document.getElementById('statusButton').innerHTML = `\r\n        &lt;i class=&quot;fas fa-spinner fa-spin&quot;&gt;&lt;\/i&gt;\r\n        Setting up websocket proxy and register service worker`;\r\n      class WebSocketProxy {\r\n        url;\r\n        handle;\r\n        bufferedAmount;\r\n        readyState;\r\n        constructor(_url) {\r\n          this.url = _url\r\n          this.handle = webSocketHandleCounter++;\r\n          this.bufferedAmount = 0;\r\n          this.shelter = null;\r\n          webSocketRefs[this.handle] = this;\r\n          webR.evalRVoid(`\r\n                        onWSOpen &lt;- options('webr_httpuv_onWSOpen')[[1]]\r\n                        if (!is.null(onWSOpen)) {\r\n                          onWSOpen(${this.handle},list(handle = ${this.handle}))\r\n                        }`)\r\n          setTimeout(() =&gt; {\r\n            this.readyState = 1;\r\n            this.onopen()},\r\n            0);\r\n        }\r\n        async send(msg) {\r\n          webR.evalRVoid(`\r\n          onWSMessage &lt;- options('webr_httpuv_onWSMessage')[[1]]\r\n          if (!is.null(onWSMessage)) {onWSMessage(${this.handle}, FALSE, '${msg}')}\r\n          `)\r\n        }\r\n      }\r\n      await webR.init();\r\n      console.log('webR ready');\r\n      (async () =&gt; {\r\n        for (; ;) {\r\n          const output = await webR.read();\r\n          switch (output.type) {\r\n            case 'stdout':\r\n              console.log(output.data)\r\n              break;\r\n            case 'stderr':\r\n              console.log(output.data)\r\n              break;\r\n            case '_webR_httpuv_TcpResponse':\r\n              const registration = await navigator.serviceWorker.getRegistration();\r\n              registration.active.postMessage({\r\n                type: &quot;wasm-http-response&quot;,\r\n                uuid: output.uuid,\r\n                response: output.data,\r\n              });\r\n              break;\r\n            case '_webR_httpuv_WSResponse':\r\n              const event = { data: output.data.message };\r\n              webSocketRefs[output.data.handle].onmessage(event);\r\n              console.log(event)\r\n              break;\r\n          }\r\n        }\r\n      })();\r\n      \/\/ TODO\r\n      const registration = await navigator.serviceWorker.register('\/wasmR\/httpuv-serviceworker.js', { scope: '\/wasmR\/' }).catch((error) =&gt; {\r\n      console.error('Service worker registration error:', error);\r\n      });\r\n      if ('serviceWorker' in navigator) {\r\n        navigator.serviceWorker.getRegistration()\r\n          .then((registration) =&gt; {\r\n            if (registration) {\r\n              const scope = registration.scope;\r\n              console.log('Service worker scope:', scope);\r\n            } else {\r\n              console.log('No registered service worker found.');\r\n            }\r\n          })\r\n          .catch((error) =&gt; {\r\n            console.error('Error retrieving service worker registration:', error);\r\n          });\r\n      } else {\r\n        console.log('Service workers not supported.');\r\n      }\r\n      await navigator.serviceWorker.ready;\r\n      window.addEventListener('beforeunload', async () =&gt; {\r\n        await registration.unregister();\r\n      });\r\n      console.log(&quot;service worker registered&quot;);\r\n      document.getElementById('statusButton').innerHTML = `\r\n        &lt;i class=&quot;fas fa-spinner fa-spin&quot;&gt;&lt;\/i&gt;\r\n        Downloading R script...\r\n      `;\r\n      await webR.evalR(&quot;download.file('&quot; + shinyScriptURL + &quot;', '&quot; + shinyScriptName + &quot;')&quot;);\r\n      console.log(&quot;file downloaded&quot;);\r\n      document.getElementById('statusButton').innerHTML = `\r\n        &lt;i class=&quot;fas fa-spinner fa-spin&quot;&gt;&lt;\/i&gt;\r\n        Installing packages...\r\n      `;\r\n      await webR.installPackages([&quot;shiny&quot;, &quot;jsonlite&quot;])\r\n      document.getElementById('statusButton').innerHTML = `\r\n        &lt;i class=&quot;fas fa-spinner fa-spin&quot;&gt;&lt;\/i&gt;\r\n        Loading app...\r\n      `;\r\n      webR.writeConsole(`\r\n          library(shiny)\r\n          runApp('` + shinyScriptName + `')\r\n      `);\r\n      \/\/ Setup listener for service worker messages\r\n      navigator.serviceWorker.addEventListener('message', async (event) =&gt; {\r\n        if (event.data.type === 'wasm-http-fetch') {\r\n          var url = new URL(event.data.url);\r\n          var pathname = url.pathname.replace(\/.*\\\\\/__wasm__\\\\\/([0-9a-fA-F-]{36})\/, &quot;&quot;);\r\n          var query = url.search.replace(\/^\\\\?\/, '');\r\n          webR.evalRVoid(`\r\n                     onRequest &lt;- options(&quot;webr_httpuv_onRequest&quot;)[[1]]\r\n                     if (!is.null(onRequest)) {\r\n                       onRequest(\r\n                         list(\r\n                           PATH_INFO = &quot;${pathname}&quot;,\r\n                           REQUEST_METHOD = &quot;${event.data.method}&quot;,\r\n                           UUID = &quot;${event.data.uuid}&quot;,\r\n                           QUERY_STRING = &quot;${query}&quot;\r\n                         )\r\n                       )\r\n                     }\r\n                     `);\r\n        }\r\n      });\r\n      \/\/ Register with service worker and get our client ID\r\n      const clientId = await new Promise((resolve) =&gt; {\r\n        navigator.serviceWorker.addEventListener('message', function listener(event) {\r\n          if (event.data.type === 'registration-successful') {\r\n            navigator.serviceWorker.removeEventListener('message', listener);\r\n            resolve(event.data.clientId);\r\n            console.log(&quot;event data:&quot;)\r\n            console.log(event.data)\r\n          }\r\n        });\r\n        registration.active.postMessage({ type: &quot;register-client&quot; });\r\n      });\r\n      console.log('I am client: ', clientId);\r\n      console.log(&quot;serviceworker proxy is ready&quot;);\r\n      \/\/ Load the WASM httpuv hosted page in an iframe\r\n      const containerDiv = document.getElementById('iframeContainer');\r\n      let iframe = document.createElement('iframe');\r\n      iframe.id = 'app';\r\n      iframe.src = `.\/__wasm__\/${clientId}\/`;\r\n      iframe.frameBorder = '0';\r\n      iframe.style.width = '100%';\r\n      iframe.style.height = '600px'; \/\/ Adjust the height as needed\r\n      iframe.style.overflow = 'auto';\r\n      containerDiv.appendChild(iframe);\r\n      \/\/ Install the websocket proxy for chatting to httpuv\r\n      iframe.contentWindow.WebSocket = WebSocketProxy;\r\n      document.getElementById('statusButton').innerHTML = `\r\n          &lt;i class=&quot;fas fa-check-circle&quot;&gt;&lt;\/i&gt;\r\n          App loaded!\r\n      `;\r\n      document.getElementById('statusButton').style.backgroundColor = 'green';\r\n      console.log(&quot;App loaded!&quot;);\r\n    } catch (error) {\r\n      console.log(&quot;Error:&quot;, error);\r\n      document.getElementById('statusButton').innerHTML = `\r\n        &lt;i class=&quot;fas fa-times-circle&quot;&gt;&lt;\/i&gt;\r\n        Something went wrong...\r\n      `;\r\n      document.getElementById('statusButton').style.backgroundColor = 'red';\r\n    }\r\n  };\r\n  loadShiny();\r\n&lt;\/script&gt;\r\n```<\/pre>\r\n\r\n\r\n\r\n\r\n<p id=\"da59\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">note that, there is<span>\u00a0<\/span><strong class=\"ly gk\">4 code<\/strong><span>\u00a0<\/span>that you must notice.<\/p>\r\n\r\n\r\n\r\n<ol class=\"\">\r\n    \r\n    \r\n    \r\n\t<li id=\"7dae\" class=\"zl zm st ly b th abg zo zp tk abh zr zs aby abi zu zv abz abj zx zy aca abk aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\"><code>Line 3\u20134<\/code><span>\u00a0<\/span>add header to<span>\u00a0<\/span><code>enable-thread.js<\/code><span>\u00a0<\/span>: github page has some permissions-policy (CORB \/ COOP \/ COEP) that blocks resource from other source page. so add this to enable it.\u00a0<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"0b31\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\"><code>Line 7<\/code>\u00a0add \u201c=html\u201d to HTML code in quarto (not just show it)<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"98e0\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\"><code>First TODO<\/code><span>\u00a0<\/span>set<span>\u00a0<\/span><strong class=\"ly gk\">app.R code via URL<\/strong>: I tried to include in repo and call it like<span>\u00a0<\/span><code>repo\/app.R<\/code>, but it didn\u2019t work. so upload<span>\u00a0<\/span><code>app.R<\/code><span>\u00a0<\/span>in your repo and call it with raw file URL<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"9941\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\"><code>Last TODO<\/code><span>\u00a0<\/span><strong class=\"ly gk\">register service worker<\/strong><span>\u00a0<\/span>along your github page:<br \/>\r\nin registration, above code use<span>\u00a0<\/span><code>\/wasmR\/httpuv-serviceworker.js<\/code><span>\u00a0<\/span>and scope<span>\u00a0<\/span><code>\/wasmR\/<\/code><span>\u00a0<\/span>but you must change to wasmR as your repository name.<\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n<p id=\"99dc\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">after complete index.qmd. render it to index.html<\/p>\r\n\r\n\r\n\r\n<blockquote class=\"acj ack acl\">\r\n\r\n\r\n\r\n<p id=\"cc2b\" class=\"zl zm acm ly b th abg zo zp tk abh zr zs aby abi zu zv abz abj zx zy aca abk aba abb yt ig bp\" data-selectable-paragraph=\"\">but result will not show in localhost.<\/p>\r\n<\/blockquote>\r\n\r\n\r\n\r\n<p id=\"244c\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">Remain step is so easy.<\/p>\r\n\r\n\r\n\r\n<ul class=\"\">\r\n    \r\n    \r\n    \r\n\t<li id=\"f20c\" class=\"zl zm st ly b th abg zo zp tk abh zr zs aby abi zu zv abz abj zx zy aca abk aba abb yt acn acc acd bp\" data-selectable-paragraph=\"\">just commit your work to repository,<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"1173\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acn acc acd bp\" data-selectable-paragraph=\"\">and build github page with that.<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"76ad\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acn acc acd bp\" data-selectable-paragraph=\"\">In page setting, do not use<span>\u00a0<\/span><code>\/docs<\/code>, just<span>\u00a0<\/span><code>\/ (root)<\/code><span>\u00a0<\/span>only worked for me. even set quarto project to render output in<span>\u00a0<\/span><code>\/docs<\/code><\/li>\r\n<\/ul>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"n p za fb jl zb\" role=\"separator\"><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze\"><\/span><\/div>\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n<h4 id=\"8b38\" class=\"xc xd st al xe xf zg tj lc xh zh tm lh xj zi xl xm xn zj xp xq xr zk xt xu xv bp\">Final repository structure<\/h4>\r\n\r\n\r\n\r\n<pre>\/repo\r\n  - index.qmd\r\n  - index.html\r\n  - \/index_files \r\n  - enable-thread.js\r\n  - httpuv-serviceworker.js\r\n  - \u2026. (readme.md and so on)<\/pre>\r\n\r\n\r\n\r\n<p id=\"787f\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">bold is essential file and js file should download from link<span> <\/span><a class=\"ay yz\" href=\"https:\/\/github.com\/georgestagg\/shiny-standalone-webr-demo\/blob\/main\/httpuv-serviceworker.js\" rel=\"nofollow\" target=\"_blank\">1<\/a>,<span> <\/span><a class=\"ay yz\" href=\"https:\/\/github.com\/josephrocca\/clip-image-sorter\/blob\/main\/enable-threads.js\" rel=\"nofollow\" target=\"_blank\">2<\/a>.<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"n p za fb jl zb\" role=\"separator\">\r\n\r\n\r\n\r\n<hr \/><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze\"><\/span><\/div>\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n<h4 id=\"a585\" class=\"xc xd st al xe xf zg tj lc xh zh tm lh xj zi xl xm xn zj xp xq xr zk xt xu xv bp\">Summary<\/h4>\r\n\r\n\r\n\r\n<p id=\"d1a4\" class=\"pw-post-body-paragraph zl zm st ly b th zn zo zp tk zq zr zs li zt zu zv ln zw zx zy ls zz aba abb yt ig bp\" data-selectable-paragraph=\"\">We\u2019ve seen how to deploy shiny as a github page with a simple example.<\/p>\r\n\r\n\r\n\r\n<p id=\"c2df\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">Let\u2019s summarize some of the pros and cons of this method.<\/p>\r\n\r\n\r\n\r\n<h6 id=\"1aa0\" class=\"acp xd st al xe ky acq kz lc ld acr le lh li acs lj lm ln act lo lr ls acu lt lw acv bp\">Pros<\/h6>\r\n\r\n\r\n\r\n<ol class=\"\">\r\n    \r\n    \r\n    \r\n\t<li id=\"c140\" class=\"zl zm st ly b th zn zo zp tk zq zr zs aby zt zu zv abz zw zx zy aca zz aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">You can deploy<span> <\/span><strong class=\"ly gk\">simple shinyapp<\/strong><span> <\/span>with static page (github page)<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"e9ae\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">You don\u2019t need to consider<span> <\/span><strong class=\"ly gk\">cost \/ scale \/ performance<\/strong><span> <\/span>since wasm uses client (User) \u2018s PC.<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"78de\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">You can<span> <\/span><strong class=\"ly gk\">extend<\/strong><span> <\/span>your shiny app with other framework like react, vue, tailwind\u2026 since shinyapp only requires just iframe and javascript code.<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"86ff\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">You don\u2019t need to consider<span> <\/span><strong class=\"ly gk\">deploy<\/strong>. (Github will do that)<\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n<h6 id=\"63c8\" class=\"acp xd st al xe ky acq kz lc ld acr le lh li acs lj lm ln act lo lr ls acu lt lw acv bp\">Cons<\/h6>\r\n\r\n\r\n\r\n<ol class=\"\">\r\n    \r\n    \r\n    \r\n\t<li id=\"0810\" class=\"zl zm st ly b th zn zo zp tk zq zr zs aby zt zu zv abz zw zx zy aca zz aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">webR is in really really really<span> <\/span><strong class=\"ly gk\">earlier stage<\/strong>. so it doesn\u2019t have much references, resources to refer.<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"9452\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">wasm shiny application requires<span> <\/span><strong class=\"ly gk\">time to initiate<\/strong><span> <\/span>webR and shiny in chrome (this is critical, it takes so much time sometime randomly)<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"3146\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">(as Leemput already mentioned)<span> <\/span><strong class=\"ly gk\">why shiny?<\/strong><span> <\/span>we can just use common web framework as UI and input, then utilize just webR not shiny.<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"ae8b\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">Heavier work (like file I\/O) doesn\u2019t supports yet in wasm shiny.<\/li>\r\n<\/ol>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"n p za fb jl zb\" role=\"separator\">\r\n\r\n\r\n\r\n<hr \/><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze\"><\/span><\/div>\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n<h4 id=\"a9fe\" class=\"xc xd st al xe xf zg tj lc xh zh tm lh xj zi xl xm xn zj xp xq xr zk xt xu xv bp\">Future work?<\/h4>\r\n\r\n\r\n\r\n<p id=\"bd5a\" class=\"pw-post-body-paragraph zl zm st ly b th zn zo zp tk zq zr zs li zt zu zv ln zw zx zy ls zz aba abb yt ig bp\" data-selectable-paragraph=\"\">I think some can be improved.<\/p>\r\n\r\n\r\n\r\n<ol class=\"\">\r\n    \r\n    \r\n    \r\n\t<li id=\"b6c7\" class=\"zl zm st ly b th abg zo zp tk abh zr zs aby abi zu zv abz abj zx zy aca abk aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">use javascript as separate file (in qmd\u2019s module script) : so quarto only requires iframe and button<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"1bd4\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">use app.R via repo not URL<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"10b2\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">render quarto page to \/docs not root: with this, quarto blog can use wasm shiny application well.<\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"9c31\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acb acc acd bp\" data-selectable-paragraph=\"\">research about what can be done or not via wasm shiny application. )I checked file upload \/ download can\u2019t)<\/li>\r\n<\/ol>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"n p za fb jl zb\" role=\"separator\">\r\n\r\n\r\n\r\n<hr \/><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze\"><\/span><\/div>\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n<h4 id=\"65e4\" class=\"xc xd st al xe xf zg tj lc xh zh tm lh xj zi xl xm xn zj xp xq xr zk xt xu xv bp\">Other ways to use webR<\/h4>\r\n\r\n\r\n\r\n<p id=\"bd99\" class=\"pw-post-body-paragraph zl zm st ly b th zn zo zp tk zq zr zs li zt zu zv ln zw zx zy ls zz aba abb yt ig bp\" data-selectable-paragraph=\"\">You may note that, there are other options to build shiny webR using<span> <\/span><strong class=\"ly gk\">golem<\/strong><span> <\/span>framework. (I\u2019ll not brief them)<\/p>\r\n\r\n\r\n\r\n<ul class=\"\">\r\n    \r\n    \r\n    \r\n\t<li id=\"e57c\" class=\"zl zm st ly b th abg zo zp tk abh zr zs aby abi zu zv abz abj zx zy aca abk aba abb yt acn acc acd bp\" data-selectable-paragraph=\"\"><a class=\"ay yz\" href=\"https:\/\/github.com\/DivadNojnarg\/golemWebR\" rel=\"nofollow\" target=\"_blank\">https:\/\/github.com\/DivadNojnarg\/golemWebR<\/a><\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"c7a5\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acn acc acd bp\" data-selectable-paragraph=\"\"><a class=\"ay yz\" href=\"https:\/\/github.com\/RinteRface\/webR4Shiny\" rel=\"nofollow\" target=\"_blank\">https:\/\/github.com\/RinteRface\/webR4Shiny<\/a><\/li>\r\n    \r\n    \r\n    \r\n\t<li id=\"af91\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acn acc acd bp\" data-selectable-paragraph=\"\"><a class=\"ay yz\" href=\"https:\/\/golem-webr.rinterface.com\/\" rel=\"nofollow\" target=\"_blank\">https:\/\/golem-webr.rinterface.com\/<\/a><\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p id=\"234a\" class=\"pw-post-body-paragraph zl zm st ly b th abg zo zp tk abh zr zs li abi zu zv ln abj zx zy ls abk aba abb yt ig bp\" data-selectable-paragraph=\"\">There is<span> <\/span><strong class=\"ly gk\">quarto template<\/strong><span> <\/span>use webR (not supports shiny yet)<\/p>\r\n\r\n\r\n\r\n<ul class=\"\">\r\n    \r\n    \r\n    \r\n\t<li id=\"5d9b\" class=\"zl zm st ly b th abg zo zp tk abh zr zs aby abi zu zv abz abj zx zy aca abk aba abb yt acn acc acd bp\" data-selectable-paragraph=\"\"><a class=\"ay yz\" href=\"https:\/\/github.com\/coatless\/quarto-webr\" rel=\"nofollow\" target=\"_blank\">https:\/\/github.com\/coatless\/quarto-webr<\/a><\/li>\r\n<\/ul>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"n p za fb jl zb\" role=\"separator\"><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze zf\"><\/span><span class=\"zc ch br zd ze\"><\/span><\/div>\r\n\r\n\r\n\r\n<div class=\"ig qf qr sq sr\">\r\n\r\n\r\n\r\n<div class=\"n p\">\r\n\r\n\r\n\r\n<div class=\"cz bm da db dc dd\">\r\n\r\n\r\n\r\n<h4 id=\"b064\" class=\"xc xd st al xe xf zg tj lc xh zh tm lh xj zi xl xm xn zj xp xq xr zk xt xu xv bp\">Thanks to community<\/h4>\r\n\r\n\r\n\r\n<ul class=\"\">\r\n    \r\n    \r\n    \r\n\t<li id=\"5632\" class=\"zl zm st ly b th zn zo zp tk zq zr zs aby zt zu zv abz zw zx zy aca zz aba abb yt acn acc acd bp\" data-selectable-paragraph=\"\"><a class=\"ay yz\" href=\"https:\/\/github.com\/georgestagg\" rel=\"nofollow\" target=\"_blank\">George Stagg<\/a><span> <\/span>for<span> <\/span><code>httpuv-serviceworker.js<\/code><\/li>\r\n    \r\n    \r\n    \r\n    \r\n\t<li id=\"f14b\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acn acc acd bp\" data-selectable-paragraph=\"\"><a class=\"ay yz\" href=\"https:\/\/github.com\/josephrocca\" rel=\"nofollow\" target=\"_blank\">Joseph rocca<\/a><span>\u00a0<\/span>for<span>\u00a0<\/span><code>enable-thread.js<\/code><\/li>\r\n    \r\n    \r\n    \r\n    \r\n\t<li id=\"a350\" class=\"zl zm st ly b th ace zo zp tk acf zr zs aby acg zu zv abz ach zx zy aca aci aba abb yt acn acc acd bp\" data-selectable-paragraph=\"\"><a class=\"ay yz\" href=\"https:\/\/github.com\/hypebright\" rel=\"nofollow\" target=\"_blank\">Veerle van Leemput<\/a><span>\u00a0<\/span>for kind introduction and help<\/li>\r\n<\/ul>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n<p id=\"42ab\" class=\"xc xd st al xe xf zg tj lc xh zh tm lh xj zi xl xm xn zj xp xq xr zk xt xu xv bp\"><br \/>\r\nIf you have question or some ideas. Let\u2019s <a href=\"mailto:jinhwan@zarathu.com\" rel=\"nofollow\" target=\"_blank\">talk<\/a>!<\/p>\r\n<span class=\"zc ch br zd ze zf\"><span style=\"font-size: 20px;font-weight: bold\"><br \/>\r\n<\/span><\/span><\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div><hr style=\"border-top:black solid 1px\" \/><a href=\"http:\/\/r-posts.com\/build-serverless-shiny-application-via-github-page\/\" rel=\"nofollow\" target=\"_blank\">Build serverless shiny application via Github page<\/a> was first posted on August 31, 2023 at 7:10 pm.<br \/>\n<div style=\"border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;\">\r\n<div style=\"text-align: center;\">To <strong>leave a comment<\/strong> for the author, please follow the link and comment on their blog: <strong><a href=\"http:\/\/r-posts.com\/build-serverless-shiny-application-via-github-page\/\"> R-posts.com<\/a><\/strong>.<\/div>\r\n<hr \/>\r\n<a href=\"https:\/\/www.r-bloggers.com\/\" rel=\"nofollow\">R-bloggers.com<\/a> offers <strong><a href=\"https:\/\/feedburner.google.com\/fb\/a\/mailverify?uri=RBloggers\" rel=\"nofollow\">daily e-mail updates<\/a><\/strong> about <a title=\"The R Project for Statistical Computing\" href=\"https:\/\/www.r-project.org\/\" rel=\"nofollow\">R<\/a> news and tutorials about <a title=\"R tutorials\" href=\"https:\/\/www.r-bloggers.com\/how-to-learn-r-2\/\" rel=\"nofollow\">learning R<\/a> and many other topics. <a title=\"Data science jobs\" href=\"https:\/\/www.r-users.com\/\" rel=\"nofollow\">Click here if you're looking to post or find an R\/data-science job<\/a>.\r\n\r\n<hr>Want to share your content on R-bloggers?<a href=\"https:\/\/www.r-bloggers.com\/add-your-blog\/\" rel=\"nofollow\"> click here<\/a> if you have a blog, or <a href=\"http:\/\/r-posts.com\/\" rel=\"nofollow\"> here<\/a> if you don't.\r\n<\/div>","protected":false},"excerpt":{"rendered":"<div style = \"width:60%; display: inline-block; float:left; \"> Simple guide for simple shiny application\u00a0 TL;DR I made\u00a0shiny\u00a0application in\u00a0github page\u00a0with\u00a0quarto. You can check code in\u00a0my github repository\u00a0and\u00a0result,\u00a0result2 How we use shiny Shiny\u00a0is R package to make user utilize R with web browser without install it. So my company &#8230;<\/div>\n<div style = \"width: 40%; display: inline-block; float:right;\"><\/div>\n<div style=\"clear: both;\"><\/div>\n","protected":false},"author":2437,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"aioseo_notices":[],"jetpack-related-posts":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/posts\/346571"}],"collection":[{"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/users\/2437"}],"replies":[{"embeddable":true,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/comments?post=346571"}],"version-history":[{"count":20,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/posts\/346571\/revisions"}],"predecessor-version":[{"id":378659,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/posts\/346571\/revisions\/378659"}],"wp:attachment":[{"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/media?parent=346571"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/categories?post=346571"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.r-bloggers.com\/wp-json\/wp\/v2\/tags?post=346571"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}