[{"data":1,"prerenderedAt":396},["ShallowReactive",2],{"article-2025-capacitor":3,"articles-[]":250},{"id":4,"title":5,"alt":5,"body":6,"category":234,"cover":235,"createDate":236,"description":226,"extension":237,"homepage":238,"meta":239,"navigation":238,"path":243,"recommend":238,"seo":244,"showCover":238,"slug":246,"stem":247,"tag":248,"updated":245,"__hash__":249},"articles\u002Farticles\u002F2025\u002Fcapacitor.md","Vueでスマホアプリ開発【Capacitor】",{"type":7,"value":8,"toc":225},"minimark",[9,13,16,19,22,25,31,40,45,52,55,59,62,67,74,77,80,90,93,97,100,103,106,113,116,124,127,130,142,145,156,162,165,171,174,182,185,191,194,197,200,206,211,218],[10,11,12],"p",{},"React Nativeのように、Vueでスマホアプリを作りたいな〜",[10,14,15],{},"Vueを普段使ってる人なら、一度は思ったことがあるのではないでしょうか。",[10,17,18],{},"一つのコードベースからiOS、Androidで動くアプリが出力される。夢がありますよね。",[10,20,21],{},"この記事では、 Vueの技術を使ってiOS、Androidアプリを作ってみた経験を書きました。",[10,23,24],{},"作ったアプリはこちらです。",[10,26,27],{},[28,29,30],"strong",{},"iOS",[10,32,33],{},[34,35,39],"a",{"href":36,"rel":37},"https:\u002F\u002Fapps.apple.com\u002Fjp\u002Fapp\u002F%E3%83%9D%E3%83%A2%E3%83%89%E3%83%BC%E3%83%AD-%E3%83%84%E3%83%AA%E3%83%BC\u002Fid6738609324",[38],"nofollow","ポモドーロツリーアプリ - App Store",[10,41,42],{},[28,43,44],{},"Android",[10,46,47],{},[34,48,51],{"href":49,"rel":50},"https:\u002F\u002Fplay.google.com\u002Fstore\u002Fapps\u002Fdetails?id=app.codedrip.PomodoroTree&pcampaignid=web_share",[38],"ポモドーロツリー - Google Play のアプリ",[10,53,54],{},"記事の最後に他にもVueを使って作ったアプリを紹介してます。",[56,57,58],"h2",{"id":58},"少し自己紹介",[10,60,61],{},"私はプライベートでNuxtで作ったWebアプリを運営しています。このWebアプリをスマホアプリ化したい。というのがこの記事の出発点です。",[10,63,64],{},[28,65,66],{},"Webアプリ",[10,68,69],{},[34,70,73],{"href":71,"rel":72},"https:\u002F\u002Fpomodorotree.com\u002Fja",[38],"ポモドーロツリー",[10,75,76],{},"普段のWebフロントエンド開発では Vue \u002F Nuxt を使っています。仕事・プライベートの両方で使っており、Vueのコンポーネント設計や状態管理には慣れている状態です。",[10,78,79],{},"スマホアプリ開発の経験については、iOSは経験がありますが、Androidの経験はほぼない状態でした。",[81,82,83,87],"ul",{},[84,85,86],"li",{},"iOS：Swiftでの業務経験あり",[84,88,89],{},"Android：Kotlinの経験はなく、昔にJavaを少し触った程度",[10,91,92],{},"そのため、「スマホアプリ自体はまったくの未経験」というわけではありませんが、\nAndroidネイティブを一から学ぶよりも、既存のVue資産を活かしてアプリ化する現実的な選択肢を探していました。",[56,94,96],{"id":95},"capacitorで作る","Capacitorで作る",[10,98,99],{},"いくつか調べる中でたどり着いたのが Capacitor です。",[10,101,102],{},"Capacitorは、Vueを含むWebアプリをスマホアプリとして動かすための仕組みで、必要に応じて Ionic というUIフレームワークと組み合わせて使うこともできます。",[10,104,105],{},"Capacitorは、WebViewをベースにした、いわゆる「ガワアプリ」を作るためのツールです。",[10,107,108,109,112],{},"スマホアプリの中で、ローカルにホストしたWebサイトを表示する仕組みになっており、",[110,111],"br",{},"\nそのWebサイト部分にVueで作ったアプリをそのまま組み込むことができます。",[10,114,115],{},"つまり、",[81,117,118,121],{},[84,119,120],{},"画面やロジックはVue（Web）",[84,122,123],{},"アプリとしての入れ物をCapacitorが用意する",[10,125,126],{},"という役割分担です。",[56,128,129],{"id":129},"実際に作ったアプリの構成",[10,131,132,133,135,136,138,139,141],{},"今回作ったスマホアプリは、既存のWebアプリをベース にしています。",[110,134],{},"\n新しくアプリ専用のUIやロジックを作る、というよりは、",[110,137],{},"\n「すでにあるVueアプリを、どうやってスマホアプリとして動かすか」",[110,140],{},"\nという考え方で構成しました。",[10,143,144],{},"全体の構成は以下のようになっています。",[81,146,147,150,153],{},[84,148,149],{},"フロントエンド：Vue",[84,151,152],{},"アプリ化：Capacitor",[84,154,155],{},"バックエンド・データ管理：Firebase（Web SDK）",[10,157,158,159,161],{},"Capacitorの中で、Vueで作ったWebアプリをそのまま読み込み、",[110,160],{},"\niOS \u002F Androidそれぞれのアプリとしてビルドしています。",[56,163,164],{"id":164},"データ管理について",[10,166,167,168,170],{},"データの保存には、iOSやAndroidのローカルDBは使わず、",[110,169],{},"\nWeb版と同じくFirebaseのWeb SDKを使ってクラウド側に保存する構成にしました。",[10,172,173],{},"ローカルDBも考えたのですが、使おうとすると、",[81,175,176,179],{},[84,177,178],{},"iOS \u002F Androidそれぞれの実装差分が出る",[84,180,181],{},"ネイティブ側のコードを触る必要が増えそう",[10,183,184],{},"といった点が気になったのでやめました。",[10,186,187,188,190],{},"Webアプリと同じ感覚で実装できるFirebaseを使うことで、",[110,189],{},"\nスマホアプリでも Webと同じコード・設計のまま 開発を進めることができました。",[56,192,193],{"id":193},"おわりに",[10,195,196],{},"すでにVueで作ったWebアプリがある場合、Capacitorとの相性は良いと感じました。",[10,198,199],{},"実際にWeb、iOS、Androidで全く同じVueコンポーネントを使うことができています。",[10,201,202,203,205],{},"「まずはWebとして作り、あとからスマホアプリにしたい」",[110,204],{},"\nというケースでは、工数を削減できる可能性が高いと思いました。",[10,207,208],{},[28,209,210],{},"他にも作ったので見てみてね",[10,212,213],{},[34,214,217],{"href":215,"rel":216},"https:\u002F\u002Fapps.apple.com\u002Fjp\u002Fapp\u002F%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E3%83%AB%E3%83%BC%E3%83%AC%E3%83%83%E3%83%88\u002Fid6535648012",[38],"ランダムルーレット｜シンプルなルーレットアプリアプリ - App Store",[10,219,220],{},[34,221,224],{"href":222,"rel":223},"https:\u002F\u002Fplay.google.com\u002Fstore\u002Fapps\u002Fdetails?id=app.codedrip.Spin&pcampaignid=web_share",[38],"ランダムルーレット｜シンプルなルーレットアプリ - Google Play のアプリ",{"title":226,"searchDepth":227,"depth":227,"links":228},"",2,[229,230,231,232,233],{"id":58,"depth":227,"text":58},{"id":95,"depth":227,"text":96},{"id":129,"depth":227,"text":129},{"id":164,"depth":227,"text":164},{"id":193,"depth":227,"text":193},"vuejs","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_title_cover_001_lu3vq4\u002Fl_title_cover_001_lu3vq4\u002Fl_text:MPLUS1p-Black.ttf_88_bold:Vue.jsで%0Aスマホアプリ%0A開発,co_rgb:374151,w_720,c_fit\u002Fv1712091289\u002Fthumbnail__003_prznvl.webp","2025\u002F12\u002F27","md",true,{"emoji":240,"type":241,"topics":242,"published":238},"🧪","tech",[],"\u002Farticles\u002F2025\u002Fcapacitor",{"title":5,"description":245},null,"capacitor","articles\u002F2025\u002Fcapacitor",[],"asiKVV0QZNkfMAlrMiSbbncwI9_GcUD9kJgqGE8c_PY",{"items":251,"total":395},[252,262,270,276,280,288,295,304,311,321,331,338,345,355,362,371,381,388],{"_path":253,"title":254,"description":255,"cover":256,"alt":254,"category":257,"categoryBasePath":258,"tags":259,"createDate":260,"homepage":238,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2026\u002Fmy-app-stack\u002F","2年半のフルプラットフォーム開発について全部書く","2年半前、人生で一番追い詰められたプロジェクトが終わりました。少しだけ時間に余裕ができたので、個人で運用していたWebアプリをリプレイスすることにしました。そしてあれこれ試行錯誤していたら、2年半経っていました。やりたかった事を一通りやり切ることができたので、こだわり部分を紹介します。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_text:MPLUS1p-Black.ttf_72_bold:フルプラットフォーム開発について全部書く,co_rgb:fff,w_720,c_fit\u002Fv1712091289\u002Fogp_my-web-app-stack_ztafxo.webp","other","\u002Farticles\u002Fcategory\u002Fother\u002F",[],"2026\u002F04\u002F08","ja",{"_path":263,"title":264,"description":265,"cover":245,"alt":245,"category":226,"categoryBasePath":266,"tags":267,"createDate":268,"homepage":269,"recommend":269,"showCover":269,"lang":261},"\u002Farticles\u002F2026\u002Fthe-goal\u002F","『ザ・ゴール ― 企業の究極の目的とは何か』を読んだ","「ザ・ゴール ― 企業の究極の目的とは何か」を読みました。","\u002Farticles\u002Fcategory\u002F",[],"2026\u002F02\u002F10",false,{"_path":271,"title":272,"description":273,"cover":245,"alt":245,"category":226,"categoryBasePath":266,"tags":274,"createDate":275,"homepage":269,"recommend":269,"showCover":269,"lang":261},"\u002Farticles\u002F2026\u002Ftidy-first\u002F","『Tidy First? ―個人で実践する経験主義的ソフトウェア設計』を読んだ","「Tidy First? ―個人で実践する経験主義的ソフトウェア設計」を読んだ。",[],"2026\u002F01\u002F31",{"_path":277,"title":5,"description":226,"cover":235,"alt":5,"category":234,"categoryBasePath":278,"tags":279,"createDate":236,"homepage":238,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fcapacitor\u002F","\u002Farticles\u002Fcategory\u002Fvuejs\u002F",[],{"_path":281,"title":282,"description":283,"cover":284,"alt":282,"category":257,"categoryBasePath":258,"tags":285,"createDate":286,"updated":287,"homepage":269,"recommend":269,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fthe-land-of-playful-fellows\u002F","紅白もちのひみつ『めっきらもっきら どおん どん』","奥さんに言われて「はっ」としました。もんもんびゃっこ達は赤いおもちを食べていて、かんたは白いおもち。これはなんらかの意味がこめられてるのでは？と思い考えてみました。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fv1712091289\u002Fthe-land-of-playful-fellows_vgkvsf",[],"2025\u002F12\u002F20","2025\u002F12\u002F22",{"_path":289,"title":290,"description":291,"cover":292,"alt":290,"category":257,"categoryBasePath":258,"tags":293,"createDate":294,"updated":294,"homepage":238,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fpixel-astrophotography\u002F","星空写真をAndroid Pixelでキレイに撮る","キャンプ場での夜空はやっぱりキレイでした。星がよく見れます。肉眼で見れるこのキレイな星空を写真に残せたら嬉しいなーと思いながら、タイマーが終わるのを待ちます。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_title_cover_001_lu3vq4\u002Fl_title_cover_001_lu3vq4\u002Fl_text:MPLUS1p-Black.ttf_88_bold:星空写真を%0APixelで%0Aキレイに撮る,co_rgb:374151,w_720,c_fit\u002Fv1712091289\u002Fpixel-astrophotography",[],"2025\u002F09\u002F29",{"_path":296,"title":297,"description":298,"cover":299,"alt":297,"category":300,"categoryBasePath":301,"tags":302,"createDate":303,"updated":303,"homepage":238,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fhosting-storybook\u002F","Storybookのダッシュボードを公開する","以前から Vue の UI ライブラリを Storybook を使って作っていました。その UI ライブラリの Storybook を静的サイトにビルドしてホスティングしてみました。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_text:MPLUS1p-Black.ttf_88_bold:Storybookの%0Aダッシュボードを%0A公開する,co_rgb:fff,w_720,c_fit\u002Fv1712091289\u002Fcover_2025_rpwog8.png","storybook","\u002Farticles\u002Fcategory\u002Fstorybook\u002F",[],"2025\u002F05\u002F28",{"_path":305,"title":306,"description":307,"cover":308,"alt":306,"category":257,"categoryBasePath":258,"tags":309,"createDate":310,"updated":310,"homepage":269,"recommend":269,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fmemo\u002F","メモは脳の排水","紙、デジタルどちらでもなんでもメモに書き出します。書き出すことで考えが整理され、ネタ帳になってくれるので重宝しています。この「脳の排水」という言葉にグッときました。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_text:MPLUS1p-Black.ttf_88_bold:メモは脳の排水,co_rgb:fff,w_720,c_fit\u002Fv1712091289\u002Fcover_2025_rpwog8.png",[],"2025\u002F05\u002F27",{"_path":312,"title":313,"description":314,"cover":315,"alt":313,"category":316,"categoryBasePath":317,"tags":318,"createDate":320,"updated":320,"homepage":238,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fa2a-guide\u002F","A2A 試してみた","A2AとはAIエージェントとAIエージェントが連携するための規格です。Googleが2025年4月に発表しました。Googleのサンプルコードを動かしてみます。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_text:MPLUS1p-Black.ttf_88_bold:A2A 試してみた,co_rgb:fff,w_720,c_fit\u002Fv1712091289\u002Fcover_2025_rpwog8.png","ai","\u002Farticles\u002Fcategory\u002Fai\u002F",[319],"AI","2025\u002F05\u002F01",{"_path":322,"title":323,"description":324,"cover":325,"alt":323,"category":326,"categoryBasePath":327,"tags":328,"createDate":329,"updated":330,"homepage":238,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fdify-self-hosted-guide\u002F","Dify をセルフホストで立ち上げる","Dify をセルフホストで立ち上げる機会があったので、手順を紹介します。Dify（ディファイ）は、AIアプリを簡単に開発できるオープンソースのプラットフォームです。クラウド版とセルフホスト版があります。今回は Dify をセルフホストで立ち上げてみます。公式と同じ手順で実行する。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_text:MPLUS1p-Black.ttf_88_bold:Dify を%0Aセルフホストで%0A立ち上げる,co_rgb:fff,w_720,c_fit\u002Fv1712091289\u002Fcover_2025_rpwog8.png","dify","\u002Farticles\u002Fcategory\u002Fdify\u002F",[],"2025\u002F04\u002F29","2025-04-29",{"_path":332,"title":333,"description":334,"cover":335,"alt":333,"category":257,"categoryBasePath":258,"tags":336,"createDate":337,"updated":337,"homepage":269,"recommend":269,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fphysical-bookstore\u002F","リアル書店の選書体験","今回で改めて書店の良さに気付けたのが良かったです。ただ、ネット通販や電子書籍には手軽に買えるなど別の良さがあると思ってます。なのでうまく使い分けていきたいです。","https:\u002F\u002Fasset.hirameki.dev\u002Fimg%2Fblog%2Fjournal%2F2025%2F20250425%2F20250425_010.webp?alt=media",[],"2025\u002F04\u002F25",{"_path":339,"title":340,"description":341,"cover":342,"alt":340,"category":316,"categoryBasePath":317,"tags":343,"createDate":344,"updated":344,"homepage":238,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fcline-guide\u002F","Cline やってみた","Clineは自分自身でコマンドを実行できるようになっています。暴走しても被害がコンテナの中だけで済むようにDevContainersを使って今回試してみました。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_text:MPLUS1p-Black.ttf_88_bold:Cline%20やってみた,co_rgb:fff,w_720,c_fit\u002Fv1712091289\u002Fcover_2025_rpwog8.png",[319],"2025\u002F04\u002F16",{"_path":346,"title":347,"description":348,"cover":349,"alt":347,"category":350,"categoryBasePath":351,"tags":352,"createDate":354,"updated":354,"homepage":238,"recommend":269,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fmy-oss-projects\u002F","今まで作った OSS プロジェクト","今まで、いくつか OSS プロジェクトを作ってきたので紹介します。番外編まで含めると全部で5つあります。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_text:MPLUS1p-Black.ttf_88_bold:今まで作った%0AOSS%20プロジェクト,co_rgb:fff,w_720,c_fit\u002Fv1712091289\u002Fcover_2025_rpwog8.png","oss","\u002Farticles\u002Fcategory\u002Foss\u002F",[353],"OSS","2025\u002F04\u002F02",{"_path":356,"title":357,"description":358,"cover":359,"alt":357,"category":257,"categoryBasePath":258,"tags":360,"createDate":361,"updated":361,"homepage":238,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fbuilt-custom-keyboard\u002F","キーボードを自作した","ずっと興味のあった自作キーボードに挑戦した記録で、遊舎工房でキットやキーキャップを選び、秋葉原で工具を買い、久しぶりのはんだ付けに苦戦しながら完成させました。","https:\u002F\u002Fasset.hirameki.dev\u002Fimg%2Fblog%2Fjournal%2F2025%2F20250309_built-custom-keyboard%2F20250309_built-custom-keyboard_010.webp?alt=media",[],"2025\u002F03\u002F09",{"_path":363,"title":364,"description":365,"cover":366,"alt":364,"category":367,"categoryBasePath":368,"tags":369,"createDate":370,"updated":370,"homepage":238,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Fcloudflare-workers-cache-layer\u002F","Cloudflare Workers でキャッシュ層を作る","画像サーバーの前段に Cloudflare Workers でキャッシュ層を作ったら転送量が大幅に減ったので記録です。やりかたです。1. 以下のコードで Workers を作りカスタムドメインを当てる。2. ソースコードの URL を Workers に割り当てたドメインに変更する。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_text:MPLUS1p-Black.ttf_88_bold:Cloudflare Workers で%0Aキャッシュ層を%0A作る,co_rgb:fff,w_720,c_fit\u002Fv1712091289\u002Fcover_2025_rpwog8.png","web","\u002Farticles\u002Fcategory\u002Fweb\u002F",[],"2025\u002F02\u002F23",{"_path":372,"title":373,"description":374,"cover":375,"alt":373,"category":376,"categoryBasePath":377,"tags":378,"createDate":379,"updated":380,"homepage":238,"recommend":269,"showCover":238,"lang":261},"\u002Farticles\u002F2022\u002Flearn-programming\u002F","プログラミング勉強のコツを調べてみた","エラーに対する態度は3パターンあります。上達が早いのはもちろん3番目のパターンです。事前に知っておくことで、エラーに直面した時に少し落ち着いて対処できそうです。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_title_cover_001_lu3vq4\u002Fl_title_cover_001_lu3vq4\u002Fl_text:MPLUS1p-Black.ttf_88_bold:プログラミング%0A勉強のコツを%0A調べてみた,co_rgb:374151,w_720,c_fit\u002Fv1642574453\u002Falfons-morales-YLSwjSy7stw-unsplash_2_1_xnt6z7.png","programming","\u002Farticles\u002Fcategory\u002Fprogramming\u002F",[],"2022\u002F05\u002F23","2025\u002F02\u002F12",{"_path":382,"title":383,"description":384,"cover":385,"alt":383,"category":257,"categoryBasePath":258,"tags":386,"createDate":387,"updated":387,"homepage":238,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2025\u002Flearn-9-years\u002F","９年間、毎日プログラミングの勉強をしてる話","仕事から帰ってきて、ご飯食べたりお風呂に入って、一息ついたらパソコンにむかって12時まで作業する。初めはビジネス書とか経済の本を読んだりしてた。それから9年経った。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_title_cover_001_lu3vq4\u002Fl_title_cover_001_lu3vq4\u002Fl_text:MPLUS1p-Black.ttf_88_bold:９年間、毎日%0Aプログラミングの勉強をしてる話,co_rgb:374151,w_720,c_fit\u002Fv1712091289\u002Fthumbnail__001_tdrr4g.webp",[],"2025\u002F02\u002F10",{"_path":389,"title":390,"description":391,"cover":392,"alt":390,"category":257,"categoryBasePath":258,"tags":393,"createDate":394,"updated":394,"homepage":269,"recommend":238,"showCover":238,"lang":261},"\u002Farticles\u002F2021\u002Fstudy-5-years\u002F","5年間ほぼ毎日プログラミングの勉強をするためにやったこと","人生の節目で一時的に勉強してない時期もありました。ですが、それ以外のほとんどの期間で毎日プログラミングを勉強しています。楽しいので、あまり勉強と思っていませんが。","https:\u002F\u002Fimage.hirameki.dev\u002Ftakasqr\u002Fimage\u002Fupload\u002Fl_text:MPLUS1p-Black.ttf_88_bold:5年間ほぼ毎日%0Aプログラミングの%0A勉強をする為に%0Aやったこと,co_rgb:fff,w_720,c_fit\u002Fv1642574453\u002Faaron-burden-QJDzYT_K8Xg-unsplash_1_xaxykh.png",[],"2021\u002F08\u002F01",18,1776498755549]