<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kazuki Yonemoto</title>
    <description>The latest articles on DEV Community by Kazuki Yonemoto (@tim_yone).</description>
    <link>https://dev.to/tim_yone</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F522927%2F4b484ec6-9920-42e1-9e4a-958026915b12.png</url>
      <title>DEV Community: Kazuki Yonemoto</title>
      <link>https://dev.to/tim_yone</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tim_yone"/>
    <language>en</language>
    <item>
      <title>shk: A Local-First Security Guardrail CLI for AI Coding Agents</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Sat, 09 May 2026 07:41:25 +0000</pubDate>
      <link>https://dev.to/tim_yone/shk-a-local-first-security-guardrail-cli-for-ai-coding-agents-3mg5</link>
      <guid>https://dev.to/tim_yone/shk-a-local-first-security-guardrail-cli-for-ai-coding-agents-3mg5</guid>
      <description>&lt;p&gt;Secret scanning often starts at Git. AI coding agents can make that too late.&lt;/p&gt;

&lt;p&gt;They can read local files, summarize logs, run commands, and transform sensitive context before anything is committed. &lt;code&gt;shk&lt;/code&gt; is a local-first CLI for that messy pre-commit space: scan secrets and PII, mask prompts, and install managed hooks for Claude Code, Cursor, and Codex.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem is no longer just "secret reaches Git"
&lt;/h2&gt;

&lt;p&gt;Most secret-scanning workflows are built around a familiar boundary: stop credentials before they land in Git, CI logs, or a release artifact.&lt;/p&gt;

&lt;p&gt;AI coding agents move that boundary earlier.&lt;/p&gt;

&lt;p&gt;An agent might read a file while following an import chain. It might summarize a pasted error log. It might run a shell command that prints &lt;code&gt;.env&lt;/code&gt; contents. It might create a new file that quietly contains a token from earlier context. None of that requires a commit.&lt;/p&gt;

&lt;p&gt;That is the gap &lt;code&gt;shk&lt;/code&gt; is trying to cover: the local, messy, pre-commit space where AI tools actually operate.&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;code&gt;shk&lt;/code&gt; does in practice
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;shk&lt;/code&gt; is not one more dashboard you have to check. It is a single Rust binary that you put around the workflows where sensitive context tends to leak:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Before sharing context with an AI tool&lt;/strong&gt;, use &lt;code&gt;shk mask&lt;/code&gt; to redact secrets and PII from a prompt, log, or snippet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Before an AI tool reads, writes, fetches, or runs something&lt;/strong&gt;, use managed hooks to audit or block risky operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Before a commit or pull request&lt;/strong&gt;, use the same scanner through Git pre-commit hooks and GitHub Actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gives you one policy file, one set of rules, and one exit-code contract across local use, AI hooks, Git, and CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick tour
&lt;/h2&gt;

&lt;p&gt;Install the latest release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-LsSf&lt;/span&gt; https://github.com/Kazuki-tam/security-harness-kit/releases/latest/download/shk-cli-installer.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Windows users can install from PowerShell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;powershell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"irm https://github.com/Kazuki-tam/security-harness-kit/releases/latest/download/shk-cli-installer.ps1 | iex"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start with a policy file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shk init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scan the current project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shk scan &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3 findings

HIGH  secret.openai_api_key  src/app.ts:12    Possible OpenAI API key detected
MED   pii.ja.phone           config/dev.ts:5  Japanese phone number detected
MED   pii.en.ssn             docs/test.md:8   US Social Security Number detected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need a machine-readable report for automation? Use JSON. Raw matched values are not emitted; findings use &lt;code&gt;redacted_value: "[REDACTED]"&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shk scan &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need to paste a production log into an AI chat? Mask it first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shk mask &amp;lt; prompt.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need to protect the commit path?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shk scan &lt;span class="nt"&gt;--staged&lt;/span&gt;
shk hooks &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The basic loop is intentionally boring: scan, review, mask, and block only when a configured threshold is met.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI-specific part: managed hooks
&lt;/h2&gt;

&lt;p&gt;The more interesting piece is &lt;code&gt;shk hooks install-ai&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead of relying on you to remember to scan every prompt, &lt;code&gt;shk&lt;/code&gt; can write managed hook entries into supported AI tool configs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Preview the changes first.&lt;/span&gt;
shk hooks install-ai &lt;span class="nt"&gt;--dry-run&lt;/span&gt;

&lt;span class="c"&gt;# Start in audit mode: log findings, never block.&lt;/span&gt;
shk hooks install-ai &lt;span class="nt"&gt;--audit&lt;/span&gt;

&lt;span class="c"&gt;# Or target one tool.&lt;/span&gt;
shk hooks install-ai &lt;span class="nt"&gt;--tool&lt;/span&gt; cursor
shk hooks install-ai &lt;span class="nt"&gt;--tool&lt;/span&gt; claude-code &lt;span class="nt"&gt;--global&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Project-level installs are the default. Global installs write to the user-level config for the selected tool.&lt;/p&gt;

&lt;p&gt;Supported integrations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Managed config&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.claude/settings.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.cursor/hooks.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codex&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.codex/config.toml&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The managed entries are tagged so they are easy to identify later (&lt;code&gt;"_shk_managed": true&lt;/code&gt; in JSON configs, or &lt;code&gt;# shk-managed-start&lt;/code&gt; / &lt;code&gt;# shk-managed-end&lt;/code&gt; in shell and TOML blocks).&lt;/p&gt;

&lt;h2&gt;
  
  
  It checks intent, not only text
&lt;/h2&gt;

&lt;p&gt;Secret scanners usually inspect content. AI hooks also need to inspect &lt;em&gt;actions&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In hook mode, &lt;code&gt;shk&lt;/code&gt; reads the AI tool's JSON hook payload and runs an action guard before scanning extracted text. The guard looks for operation shapes such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reads or writes involving sensitive paths.&lt;/li&gt;
&lt;li&gt;Commands that dump &lt;code&gt;.env&lt;/code&gt;-style files.&lt;/li&gt;
&lt;li&gt;Destructive recursive removal.&lt;/li&gt;
&lt;li&gt;Direct database mutation commands.&lt;/li&gt;
&lt;li&gt;Privilege or system configuration changes.&lt;/li&gt;
&lt;li&gt;External transfer commands.&lt;/li&gt;
&lt;li&gt;Package-manager operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The default &lt;code&gt;recommended&lt;/code&gt; profile is conservative. A &lt;code&gt;strict&lt;/code&gt; profile can also block opaque execution forms such as &lt;code&gt;bash -c&lt;/code&gt;, &lt;code&gt;python -c&lt;/code&gt;, and &lt;code&gt;node -e&lt;/code&gt;, because pretending to safely interpret every nested command string is usually worse than being explicit about the risk.&lt;/p&gt;

&lt;p&gt;You can tune this in &lt;code&gt;shk.toml&lt;/code&gt; with &lt;code&gt;[action_guard]&lt;/code&gt; allow and deny patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audit first, then block
&lt;/h2&gt;

&lt;p&gt;Hooks make decisions through exit codes, so the contract is small:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No finding at or above the active threshold, or audit/post-hook completed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Scan findings met or exceeded the active threshold.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A blocking AI pre-hook fired, or &lt;code&gt;shk scan --staged&lt;/code&gt; ran outside a Git repo.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;--audit&lt;/code&gt; always exits &lt;code&gt;0&lt;/code&gt;. Post-tool hooks also always exit &lt;code&gt;0&lt;/code&gt;, because the operation already happened and the useful behavior is reporting, not pretending to undo it.&lt;/p&gt;

&lt;p&gt;That makes rollout straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shk hooks install-ai &lt;span class="nt"&gt;--audit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let it run for a few days. Review &lt;code&gt;.shk/audit.log&lt;/code&gt;. The log is metadata-only: counts, tool name, hook phase, display path, suppressed count, and maximum severity. It does not store raw matched values.&lt;/p&gt;

&lt;p&gt;Once the noise level is acceptable, reinstall without &lt;code&gt;--audit&lt;/code&gt; and let high-severity pre-hook findings block.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same binary for Git and CI
&lt;/h2&gt;

&lt;p&gt;AI hooks are the new boundary, but Git still matters.&lt;/p&gt;

&lt;p&gt;Install a managed pre-commit hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shk hooks &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate a GitHub Actions workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shk ci init github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated workflow installs the prebuilt release binary and runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shk scan &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt; &lt;span class="nt"&gt;--fail-on&lt;/span&gt; high
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also uses a few defaults I wanted out of the box:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;permissions: contents: read&lt;/code&gt; for minimal &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; scope.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;concurrency: cancel-in-progress: true&lt;/code&gt; so newer PR pushes cancel stale runs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;actions/checkout@v6&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Release installer instead of &lt;code&gt;cargo install&lt;/code&gt;, so CI does not rebuild a Rust toolchain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also generate rollout variants when you need them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;shk ci init github --mode audit&lt;/code&gt; for non-blocking CI adoption.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shk ci init github --shk-version v0.2.3&lt;/code&gt; for reproducible pinned installs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A few workflows beyond scanning
&lt;/h2&gt;

&lt;p&gt;These are the commands that make &lt;code&gt;shk&lt;/code&gt; feel less like a one-off scanner and more like a local security harness:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;shk doctor&lt;/code&gt; checks project hygiene, including ignore coverage and plaintext &lt;code&gt;.env&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shk doctor ignore --fix&lt;/code&gt; appends missing required patterns to &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shk env dotenvx import-keys .env.keys&lt;/code&gt; moves dotenvx private keys into the OS credential store.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shk env dotenvx run -- npm test&lt;/code&gt; injects stored dotenvx keys only into the child process.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shk secrets push&lt;/code&gt; pushes dotenv payloads into AWS Secrets Manager or GCP Secret Manager through the official &lt;code&gt;aws&lt;/code&gt; / &lt;code&gt;gcloud&lt;/code&gt; CLIs, with dry-run, audit logging, and PII pre-scan.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shk skills install&lt;/code&gt; deploys an embedded agent skill for Claude Code, Codex, and Cursor so agents know how to call &lt;code&gt;shk&lt;/code&gt; in the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these are optional. The tool is still useful if you only use &lt;code&gt;scan&lt;/code&gt;, &lt;code&gt;mask&lt;/code&gt;, and hooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Suppression without pasting secrets into config
&lt;/h2&gt;

&lt;p&gt;False positives happen. Test fixtures happen. Public demo values happen.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shk&lt;/code&gt; supports a few suppression shapes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inline comments such as &lt;code&gt;# shk-ignore &amp;lt;rule_id&amp;gt;&lt;/code&gt; and &lt;code&gt;# shk-ignore-next-line &amp;lt;rule_id&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Path-based &lt;code&gt;[[allowlist]]&lt;/code&gt; entries in &lt;code&gt;shk.toml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Value-specific suppression using &lt;code&gt;value_hash = "sha256-hmac:..."&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The value hash is not encryption. It is a deterministic HMAC-SHA256 fingerprint over the raw value and rule id, so someone with the candidate value can recompute it. Its purpose is narrower and practical: your policy file should not become the place where people paste the secret they are trying to suppress.&lt;/p&gt;

&lt;p&gt;Expired allowlist entries turn into low-severity warning findings instead of silently disappearing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it intentionally does not promise
&lt;/h2&gt;

&lt;p&gt;Security tooling gets dangerous when it overstates its guarantees, so here is the honest scope.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shk&lt;/code&gt; is pattern-based. Built-in rules combine hand-tuned &lt;code&gt;shk&lt;/code&gt; detections with generated &lt;code&gt;secret.gitleaks.*&lt;/code&gt; rules adapted from the gitleaks default configuration. That covers many common providers and formats, but false positives and false negatives are both possible.&lt;/p&gt;

&lt;p&gt;The PII rules are designed for "do not paste this into an AI prompt" hygiene. They are not compliance evidence.&lt;/p&gt;

&lt;p&gt;The action guard is heuristic. It can flag risky operation shapes in hook payloads, but it is not a shell interpreter and should not pretend to be one.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shk&lt;/code&gt; is also not a replacement for a secret manager, a cloud provider's scanning features, or a dedicated enterprise secret-scanning platform. It is a local guardrail layer for the part of development where AI tools read, transform, and generate context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it on an existing repo
&lt;/h2&gt;

&lt;p&gt;The smallest useful sequence is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shk init
shk scan &lt;span class="nb"&gt;.&lt;/span&gt;
shk hooks install-ai &lt;span class="nt"&gt;--audit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the audit log looks reasonable after a short soak period, reinstall without &lt;code&gt;--audit&lt;/code&gt; and block on high-severity pre-hook findings. If it is noisy, tune &lt;code&gt;[thresholds]&lt;/code&gt;, &lt;code&gt;[[allowlist]]&lt;/code&gt;, and &lt;code&gt;[action_guard]&lt;/code&gt; first.&lt;/p&gt;

&lt;p&gt;The goal is not to make the tool dramatic. The goal is to make secrets, PII, and risky AI operations visible before they leave the local development boundary.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/Kazuki-tam/security-harness-kit" rel="noopener noreferrer"&gt;github.com/Kazuki-tam/security-harness-kit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; Installation, Commands, Configuration, Detection Model, and GitHub Actions integration are linked from the README.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License:&lt;/strong&gt; MIT.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Issues, rule contributions, and false-positive reports are welcome. The rule set gets better as more real codebases run through it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Next-Stage: A Modern Next.js Starter Template for AI-Driven Development</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Tue, 11 Mar 2025 15:09:17 +0000</pubDate>
      <link>https://dev.to/tim_yone/next-stage-a-modern-nextjs-starter-template-for-ai-driven-development-238b</link>
      <guid>https://dev.to/tim_yone/next-stage-a-modern-nextjs-starter-template-for-ai-driven-development-238b</guid>
      <description>&lt;p&gt;&lt;a href="https://next-stage-demo.vercel.app/" rel="noopener noreferrer"&gt;Next-Stage&lt;/a&gt; is a cutting-edge starter template built on &lt;strong&gt;Next.js&lt;/strong&gt;, designed specifically for developers looking to leverage modern web development practices with AI-assisted workflows.&lt;/p&gt;

&lt;p&gt;This template combines the latest technologies and best practices to provide a robust foundation for building type-safe, performant web applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo:&lt;/strong&gt; &lt;a href="https://next-stage-demo.vercel.app/" rel="noopener noreferrer"&gt;https://next-stage-demo.vercel.app/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Technology Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;Next.js (App Router)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Package Manager&lt;/td&gt;
&lt;td&gt;Bun&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Framework&lt;/td&gt;
&lt;td&gt;Hono&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI Components&lt;/td&gt;
&lt;td&gt;shadcn/ui&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Tailwind CSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form Management&lt;/td&gt;
&lt;td&gt;React Hook Form&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validation&lt;/td&gt;
&lt;td&gt;Zod&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linting &amp;amp; Formatting&lt;/td&gt;
&lt;td&gt;Biome&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Markup Linting&lt;/td&gt;
&lt;td&gt;Markuplint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E2E Testing&lt;/td&gt;
&lt;td&gt;Playwright&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supply Chain Security&lt;/td&gt;
&lt;td&gt;Bun Security Scanner&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🔑 Key Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Type-Safe Development Environment
&lt;/h3&gt;

&lt;p&gt;Next-Stage provides end-to-end type safety throughout your application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt; Integration&lt;/strong&gt;: Built with TypeScript strict mode for comprehensive type checking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://zod.dev/" rel="noopener noreferrer"&gt;Zod&lt;/a&gt; Validation&lt;/strong&gt;: Schema-based validation for forms and API requests with type inference&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript-Safe API Responses&lt;/strong&gt;: Structured API response types for consistent client-server communication&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Modern Frontend Architecture
&lt;/h3&gt;

&lt;p&gt;The template leverages the latest in frontend development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; with App Router&lt;/strong&gt;: Utilizing React Server Components and the latest features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;React&lt;/a&gt;&lt;/strong&gt;: The latest React with improved performance and new features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt;&lt;/strong&gt;: Next-generation utility-first CSS framework&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;shadcn/ui&lt;/a&gt; Components&lt;/strong&gt;: Beautiful, accessible UI components built with Radix UI&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Robust API Layer with Hono
&lt;/h3&gt;

&lt;p&gt;Next-Stage features a powerful API implementation using &lt;a href="https://hono.dev/" rel="noopener noreferrer"&gt;Hono&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Efficient Routing&lt;/strong&gt;: Clean API route organization with Hono's routing system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request Validation&lt;/strong&gt;: Integrated Zod validation via &lt;code&gt;@hono/zod-validator&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://hono.dev/docs/guides/rpc" rel="noopener noreferrer"&gt;RPC&lt;/a&gt; Implementation&lt;/strong&gt;: Type-safe Remote Procedure Call functionality for seamless client-server communication&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advanced Form Handling
&lt;/h3&gt;

&lt;p&gt;The template includes a comprehensive form management solution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://react-hook-form.com/" rel="noopener noreferrer"&gt;React Hook Form&lt;/a&gt;&lt;/strong&gt;: Performant, flexible form management with minimal re-renders&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zod Integration&lt;/strong&gt;: Type-safe form validation through &lt;code&gt;@hookform/resolvers&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Supply Chain Security
&lt;/h3&gt;

&lt;p&gt;Next-Stage implements proactive protection against supply chain attacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://bun.sh/docs/runtime/bunfig#install-security-scanner" rel="noopener noreferrer"&gt;Bun Security Scanner&lt;/a&gt;&lt;/strong&gt;: Configurable security scanning before package installation (uses &lt;a href="https://github.com/SocketDev/bun-security-scanner" rel="noopener noreferrer"&gt;@socketsecurity/bun-security-scanner&lt;/a&gt; by default)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimum Release Age&lt;/strong&gt;: Enforces a 1-day waiting period for new package versions to allow community detection of malicious packages&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Developer Experience Optimizations
&lt;/h3&gt;

&lt;p&gt;Next-Stage prioritizes developer productivity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://bun.sh/" rel="noopener noreferrer"&gt;Bun&lt;/a&gt; Package Manager&lt;/strong&gt;: Fast, all-in-one JavaScript runtime and package manager&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://turbo.build/" rel="noopener noreferrer"&gt;Turbopack&lt;/a&gt;&lt;/strong&gt;: Default bundler in Next.js for lightning-fast builds and hot module replacement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://biomejs.dev/" rel="noopener noreferrer"&gt;Biome&lt;/a&gt;&lt;/strong&gt;: Modern, fast JavaScript/TypeScript linting and formatting (replaces ESLint + Prettier)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://markuplint.dev/" rel="noopener noreferrer"&gt;Markuplint&lt;/a&gt;&lt;/strong&gt;: JSX/TSX markup linting for high-quality, accessible UI components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://playwright.dev/" rel="noopener noreferrer"&gt;Playwright&lt;/a&gt;&lt;/strong&gt;: End-to-end testing with browser automation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 AI-Driven Development
&lt;/h2&gt;

&lt;p&gt;Next-Stage is built with AI-assisted development in mind, providing comprehensive support for multiple AI coding tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Universal AI Agent Support
&lt;/h3&gt;

&lt;p&gt;The project includes &lt;code&gt;AGENTS.md&lt;/code&gt; following the &lt;a href="https://agents.md/" rel="noopener noreferrer"&gt;agents.md standard&lt;/a&gt; — a universal format that works across all AI coding agents and tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supported AI Tools
&lt;/h3&gt;

&lt;h4&gt;
  
  
  AI Editors
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Editor&lt;/th&gt;
&lt;th&gt;Configuration Location&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.cursor.com/" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.cursor/rules/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://codeium.com/windsurf" rel="noopener noreferrer"&gt;Windsurf&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.windsurf/rules/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://kiro.dev/" rel="noopener noreferrer"&gt;Kiro&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.kiro/steering/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  AI CLI Tools
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Configuration File&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.claude.com/product/claude-code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.cloud.google.com/gemini/docs/codeassist/gemini-cli" rel="noopener noreferrer"&gt;Google Gemini CLI&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GEMINI.md&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Rule File Hierarchy
&lt;/h3&gt;

&lt;p&gt;The project maintains a hierarchical rule system for consistent AI-driven development:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Base Rules&lt;/strong&gt; (&lt;code&gt;_llm-rules/&lt;/code&gt; directory):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;core-rule.md&lt;/code&gt;: Core task execution methodology&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nextjs-rule.md&lt;/code&gt;: Next.js specific development patterns&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test-rule.md&lt;/code&gt;: Testing guidelines and best practices&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Universal Format&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AGENTS.md&lt;/code&gt;: Universal format following agents.md standard&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tool-Specific Files&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;GEMINI.md&lt;/code&gt;, and generated editor-specific rules&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Generating Editor-Specific Rules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate rules for specific editors&lt;/span&gt;
bun run rules:cursor
bun run rules:windsurf
bun run rules:copilot
bun run rules:kiro

&lt;span class="c"&gt;# Generate rules for all supported editors&lt;/span&gt;
bun run rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Next.js DevTools MCP Integration
&lt;/h3&gt;

&lt;p&gt;This project includes &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/next-devtools-mcp" rel="noopener noreferrer"&gt;Next.js DevTools MCP&lt;/a&gt;&lt;/strong&gt; integration for AI coding assistants that support the &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;Model Context Protocol (MCP)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key MCP Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MCP tools for automating Next.js upgrades and Cache Components setup&lt;/li&gt;
&lt;li&gt;Pre-configured prompts for common Next.js development tasks&lt;/li&gt;
&lt;li&gt;Direct access to Next.js documentation and best practices&lt;/li&gt;
&lt;li&gt;Browser automation integration with Playwright&lt;/li&gt;
&lt;li&gt;Access to internal state, diagnostics, and errors from running dev servers&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📁 Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;next-stage/
├── public/               # Static assets
├── src/
│   ├── app/              # App Router routes
│   │   ├── _components/  # Page-specific components
│   │   ├── _styles/      # Page-specific styles
│   │   ├── layout.tsx    # Root layout
│   │   └── page.tsx      # Home page
│   ├── components/       # Reusable UI components
│   │   ├── layout/       # Layout components (header, footer)
│   │   └── ui/           # shadcn/ui components
│   ├── config/           # Configuration files
│   ├── lib/              # Utility functions
│   └── types/            # Type definitions
├── e2e/                  # E2E tests (Playwright)
├── _llm-rules/           # Base rules for AI-assisted development
├── _llm-docs/            # Documentation for AI-assisted development
├── _tasks/               # Build tasks and scripts
├── AGENTS.md             # Universal AI agent instructions
├── CLAUDE.md             # Claude CLI specific instructions
├── GEMINI.md             # Gemini CLI specific instructions
└── ...                   # Config files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Colocation Pattern
&lt;/h3&gt;

&lt;p&gt;Next-Stage implements the colocation pattern for better organization:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Page-specific resources&lt;/strong&gt;: Components, actions, and hooks are located within the page directory using underscore prefixes (&lt;code&gt;_components/&lt;/code&gt;, &lt;code&gt;_actions/&lt;/code&gt;, &lt;code&gt;_hooks/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-cutting resources&lt;/strong&gt;: Domain-independent components are kept in top-level directories&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear separation&lt;/strong&gt;: Underscore prefixes distinguish page-specific directories from route segments&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Clone the Repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bunx create-next-app@latest my-app &lt;span class="nt"&gt;--example&lt;/span&gt; https://github.com/Kazuki-tam/next-stage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Install Dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
bun &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Environment Setup (Optional)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env.local
&lt;span class="c"&gt;# Edit .env.local with your environment variables&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Start the Development Server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Open Your Browser
&lt;/h3&gt;

&lt;p&gt;Navigate to &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; to see your application running.&lt;/p&gt;




&lt;h2&gt;
  
  
  📋 Available Commands
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bun dev&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start development server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bun build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build for production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bun start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start production server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bun run lint&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run all linters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bun run format&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Format code with Biome&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bun run check&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run linting, formatting, and type checking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bun run test:unit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run unit tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bun run test:e2e&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run E2E tests with Playwright&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bun run test:e2e:ui&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run E2E tests with UI mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bun run rules&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate AI editor rules&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🚢 Deployment
&lt;/h2&gt;

&lt;p&gt;The easiest way to deploy your Next.js app is to use the &lt;a href="https://vercel.com/new" rel="noopener noreferrer"&gt;Vercel Platform&lt;/a&gt; from the creators of Next.js.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://nextjs.org/docs/app/building-your-application/deploying" rel="noopener noreferrer"&gt;Next.js deployment documentation&lt;/a&gt; for more details.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Conclusion
&lt;/h2&gt;

&lt;p&gt;Next-Stage provides a solid foundation for modern web application development with Next.js. Its focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type Safety&lt;/strong&gt;: End-to-end TypeScript with Zod validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer Experience&lt;/strong&gt;: Fast builds with Turbopack and Bun&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-Driven Development&lt;/strong&gt;: Comprehensive support for AI coding tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern Stack&lt;/strong&gt;: React, Tailwind CSS, and the latest ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you're building a small project or a large-scale application, Next-Stage gives you the tools and patterns needed to succeed, with a special emphasis on leveraging AI assistance to accelerate your development workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Take the next step in your web development journey with Next-Stage!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Display Cart Attributes Information Using Shopify Checkout UI Extensions</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Fri, 16 Aug 2024 15:25:07 +0000</pubDate>
      <link>https://dev.to/tim_yone/how-to-display-cart-attributes-information-using-shopify-checkout-ui-extensions-4oe2</link>
      <guid>https://dev.to/tim_yone/how-to-display-cart-attributes-information-using-shopify-checkout-ui-extensions-4oe2</guid>
      <description>&lt;p&gt;Traditionally, additional scripts were commonly used to display cart attributes on the thank you page of Shopify stores. However, this method is now deprecated, and the use of Checkout Extensibility is recommended.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://help.shopify.com/en/manual/checkout-settings/customize-checkout-configurations/checkout-extensibility" rel="noopener noreferrer"&gt;Checkout Extensibility upgrade guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To display cart attributes on the thank you page or order status page using Checkout Extensibility, the process is slightly more complex than the traditional method, but can be implemented with the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a custom app using Checkout UI extensions&lt;/li&gt;
&lt;li&gt;Create a UI component to output cart attribute values&lt;/li&gt;
&lt;li&gt;Modify the configuration file&lt;/li&gt;
&lt;li&gt;Launch the custom app in a local environment&lt;/li&gt;
&lt;li&gt;Deploy the custom app&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Create a Custom App Using Checkout UI Extensions
&lt;/h2&gt;

&lt;p&gt;Checkout Extensibility offers several features for customization purposes. In this case, we'll use Checkout UI extensions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmibwx0d31az61sq1j4o2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmibwx0d31az61sq1j4o2.png" alt="Image description" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Checkout UI extensions is a feature for extending the UI of the checkout page, allowing you to display components on the thank you page or order status page. Previously only available for Shopify Plus plan, it's now accessible for Basic plan and above.&lt;/p&gt;

&lt;p&gt;There are restrictions on the scope of Checkout UI extensions depending on the plan.&lt;br&gt;
Details are provided in the Summary section.&lt;/p&gt;

&lt;p&gt;Set up the custom app development environment with an Extension-only app. If you already have a custom app, you can start from the generate extension step.&lt;/p&gt;

&lt;p&gt;An Extension-only app is an app that doesn't have an app screen in the Shopify admin panel and is specialized for extensions. The entire extension app is hosted on Shopify, so there's no need to prepare separate infrastructure for the app. You can develop it with a feeling similar to CLI theme building.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://shopify.dev/docs/apps/build/app-extensions/build-extension-only-app" rel="noopener noreferrer"&gt;Build an extension-only app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This guide assumes the use of Shopify CLI. If you're new to it, please check &lt;a href="https://shopify.dev/docs/apps/build/cli-for-apps" rel="noopener noreferrer"&gt;the Shopify CLI official documentation&lt;/a&gt; for installation instructions.&lt;/p&gt;

&lt;p&gt;Use the following command to initialize the custom app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm create @shopify/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Answer the prompts to set up your project name, installation store, etc. We'll proceed with a TypeScript environment here.&lt;/p&gt;

&lt;p&gt;Once the project is created, navigate to the target directory and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm shopify app generate extension
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When asked which type of extension to create, select Checkout UI.&lt;br&gt;
Name your extension and initialize it. We'll proceed with a React TypeScript environment.&lt;/p&gt;

&lt;p&gt;Necessary files should now be generated in the extensions directory.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Create a UI Component to Output Cart Attribute Values
&lt;/h2&gt;

&lt;p&gt;Once the custom app development environment is set up, create a UI component to output cart attribute values.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;To retrieve cart attribute values, you need to implement a form using cart attributes on the cart page. Adjust the attribute names according to your expected cart attributes.&lt;/p&gt;

&lt;p&gt;Let's implement an example where delivery date and time information is managed by cart attributes.&lt;/p&gt;

&lt;p&gt;We assume the cart attribute names are set as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;delivery_date&lt;/code&gt;: Desired delivery date&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;delivery_time&lt;/code&gt;: Desired delivery time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article doesn't cover how to set up cart attributes in detail, but please refer to the following document to set up a form on the cart page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://shopify.dev/docs/api/liquid/objects/cart#cart-attributes" rel="noopener noreferrer"&gt;https://shopify.dev/docs/api/liquid/objects/cart#cart-attributes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the Checkout.tsx file and edit it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Heading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;BlockStack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;useTranslate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;useAttributeValues&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;reactExtension&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@shopify/ui-extensions-react/checkout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;reactExtension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;purchase.thank-you.block.render&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Extension&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Extension&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;translate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useTranslate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;delivery_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delivery_time&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAttributeValues&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delivery_date&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delivery_time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BlockStack&lt;/span&gt;
      &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tight"&lt;/span&gt;
      &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"base"&lt;/span&gt;
      &lt;span class="na"&gt;cornerRadius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"base"&lt;/span&gt;
      &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"base"&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Heading&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Heading&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deliveryDate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;delivery_date&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Not specified&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deliveryTime&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;delivery_time&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Not specified&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;BlockStack&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;p&gt;The following components are used, but feel free to change them as needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://shopify.dev/docs/api/checkout-ui-extensions/unstable/components/titles-and-text/heading" rel="noopener noreferrer"&gt;Heading&lt;/a&gt;: Output heading&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://shopify.dev/docs/api/checkout-ui-extensions/unstable/components/titles-and-text/text" rel="noopener noreferrer"&gt;Text&lt;/a&gt;: Output text&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://shopify.dev/docs/api/checkout-ui-extensions/unstable/components/structure/blockstack" rel="noopener noreferrer"&gt;BlockStack&lt;/a&gt;: Stack elements vertically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://shopify.dev/docs/api/checkout-ui-extensions/2023-04/components" rel="noopener noreferrer"&gt;https://shopify.dev/docs/api/checkout-ui-extensions/2023-04/components&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  React Hooks
&lt;/h3&gt;

&lt;p&gt;The following hooks are used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://shopify.dev/docs/api/checkout-ui-extensions/2023-04/react-hooks/localization/usetranslate" rel="noopener noreferrer"&gt;useTranslate (optional)&lt;/a&gt;: Multilingual support&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://shopify.dev/docs/api/checkout-ui-extensions/2023-04/react-hooks/attributes/useattributevalues" rel="noopener noreferrer"&gt;useAttributeValues&lt;/a&gt;: Retrieve attribute values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;useTranslate&lt;/code&gt; hook is used for multilingual support, so you can omit it if not needed. If you use it, modify the file information in the locales folder as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;extensions/extension-name/locales/en.default.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Delivery Date and Time"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"deliveryDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Delivery Date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"deliveryTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Delivery Time"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;useAttributeValues&lt;/code&gt; is necessary to retrieve cart attribute values. Use it by specifying attribute names as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;delivery_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delivery_time&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAttributeValues&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delivery_date&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delivery_time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://shopify.dev/docs/api/checkout-ui-extensions/2023-04/react-hooks/attributes/useattributevalues" rel="noopener noreferrer"&gt;https://shopify.dev/docs/api/checkout-ui-extensions/2023-04/react-hooks/attributes/useattributevalues&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reactExtension&lt;/code&gt; is a required function for outputting components. Specify the target as the first argument. The target indicates where the extension will be applied.&lt;/p&gt;

&lt;p&gt;Here, we specify &lt;code&gt;purchase.thank-you.block.render&lt;/code&gt; to output on the thank you page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://shopify.dev/docs/api/checkout-ui-extensions/unstable/targets/block/purchase-thank-you-block-render" rel="noopener noreferrer"&gt;https://shopify.dev/docs/api/checkout-ui-extensions/unstable/targets/block/purchase-thank-you-block-render&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Modify the Configuration File
&lt;/h3&gt;

&lt;p&gt;Open the &lt;code&gt;shopify.extension.toml&lt;/code&gt; file and modify the target. Note that you need to register the target in the toml file as well as in the component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# extensions/extension-name/shopify.extension.toml&lt;/span&gt;
&lt;span class="nn"&gt;[[extensions.targeting]]&lt;/span&gt;
&lt;span class="py"&gt;module&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"./src/Checkout.tsx"&lt;/span&gt;
&lt;span class="py"&gt;target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"purchase.thank-you.block.render"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Launch the Custom App in a Local Environment
&lt;/h3&gt;

&lt;p&gt;Launch the custom app in a local environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After launching, press &lt;code&gt;p&lt;/code&gt; to open the preview and confirm that the cart attribute values are displayed on the thank you page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;› Press p │ preview in your browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foj4sqn0gskazjdz677xc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foj4sqn0gskazjdz677xc.png" alt="Image description" width="800" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7phe5kc00pg4p8rgvce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7phe5kc00pg4p8rgvce.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also display cart attribute values on the order status page by adding an extension and changing the target.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;reactExtension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;customer-account.order-status.block.render&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Extension&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[[extensions.targeting]]&lt;/span&gt;
&lt;span class="py"&gt;module&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"./src/Checkout.tsx"&lt;/span&gt;
&lt;span class="py"&gt;target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"customer-account.order-status.block.render"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://shopify.dev/docs/api/checkout-ui-extensions/2024-07/targets/block/customer-account-order-status-block-render" rel="noopener noreferrer"&gt;https://shopify.dev/docs/api/checkout-ui-extensions/2024-07/targets/block/customer-account-order-status-block-render&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F098e4wsr8cnbh4c9gjg7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F098e4wsr8cnbh4c9gjg7.png" alt="Image description" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Deploy the Custom App
&lt;/h2&gt;

&lt;p&gt;Once development in the local environment is complete, deploy the custom app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm that the app is reflected in the "App Management" section of the Partner Dashboard. Install the app in your store and check it. A customization path is set up in the "Checkout" section of the store admin panel.&lt;/p&gt;

&lt;p&gt;Add the app block and confirm that the elements are displayed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Note
&lt;/h2&gt;

&lt;p&gt;The components available in Checkout UI extensions are strictly limited. Therefore, you cannot use custom UI components or HTML tags.&lt;/p&gt;

&lt;p&gt;Even if you write unavailable tags and errors occur, no error messages will be displayed on the front-end screen. It's recommended to check the terminal for error messages regularly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;We've introduced how to display cart attribute values using Checkout UI extensions. By using Checkout Extensibility, you can achieve safer and more flexible customization.&lt;/p&gt;

&lt;p&gt;However, the applicable range differs depending on the plan, so please check the available range before proceeding with implementation. The content introduced in this article is available for Basic plans and above. (As of August 16, 2024)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvdt5x1wo8hen4oafs8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvdt5x1wo8hen4oafs8a.png" alt="Image description" width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://help.shopify.com/en/manual/checkout-settings/customize-checkout-configurations" rel="noopener noreferrer"&gt;https://help.shopify.com/en/manual/checkout-settings/customize-checkout-configurations&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>shopify</category>
    </item>
    <item>
      <title>Automating Slack Notifications for Google Forms Responses: A Simple Guide Using Google Apps Script (GAS) and Slack App</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Mon, 18 Dec 2023 02:39:09 +0000</pubDate>
      <link>https://dev.to/tim_yone/automating-slack-notifications-for-google-forms-responses-a-simple-guide-using-google-apps-script-gas-and-slack-app-gc1</link>
      <guid>https://dev.to/tim_yone/automating-slack-notifications-for-google-forms-responses-a-simple-guide-using-google-apps-script-gas-and-slack-app-gc1</guid>
      <description>&lt;p&gt;You may want to notify your internal Slack channels when responses are received from Google Forms. While there are several approaches to implementation, including using integration tools, this article introduces a method using Google Apps Script (GAS) and Slack App. &lt;/p&gt;

&lt;p&gt;I personally recommend this method for its simplicity and flexibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article involves some programming, but it is presented in a way that even non-engineers can easily implement by copy-pasting.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The necessary steps for implementation are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating a Google Form&lt;/li&gt;
&lt;li&gt;Creating a Slack App&lt;/li&gt;
&lt;li&gt;Creating a Google Apps Script&lt;/li&gt;
&lt;li&gt;Setting up Google Apps Script Triggers&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating a Google Form
&lt;/h2&gt;

&lt;p&gt;First, create a form. You are free to set up the form items as you like. Here, I created a form with the following items:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name of person in Charge: Short Text&lt;/li&gt;
&lt;li&gt;Email Address: Short Text&lt;/li&gt;
&lt;li&gt;Content of Inquiry: Long Text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopbn46rkex6membjlhfn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopbn46rkex6membjlhfn.png" alt="Image description" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.google.com/intl/en_us/forms/about/" rel="noopener noreferrer"&gt;https://www.google.com/intl/en_us/forms/about/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Slack App
&lt;/h2&gt;

&lt;p&gt;Click the link below and select &lt;code&gt;Create New App&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://api.slack.com/apps" rel="noopener noreferrer"&gt;https://api.slack.com/apps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose &lt;code&gt;From scratch&lt;/code&gt;, register the app name and workspace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdfj6etg413cs41uu5ox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdfj6etg413cs41uu5ox.png" alt="Image description" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set up the app display settings. You can choose any content you like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F54o76oijjbzp5yv03ozj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F54o76oijjbzp5yv03ozj.png" alt="Image description" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the admin panel's left sidebar, select Incoming Webhooks, turn it ON to activate. Click &lt;code&gt;Add New Webhook to Workspace&lt;/code&gt;, and select the channel to receive notifications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn80hj9f7z8qfkt6yxc1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn80hj9f7z8qfkt6yxc1h.png" alt="Image description" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy and save the &lt;code&gt;Webhook URL&lt;/code&gt; of the activated channel.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a Google Apps Script
&lt;/h2&gt;

&lt;p&gt;Create a script to forward responses from Google Forms to Slack. Open the script editor from the form you created earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft4hs2zf8lc83t5jzgax5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft4hs2zf8lc83t5jzgax5.png" alt="Image description" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy and paste the following code into the editor, replacing &lt;code&gt;SLACK_WEBHOOK_URL&lt;/code&gt; with the &lt;code&gt;Webhook&lt;/code&gt; URL you copied earlier. Save the file as &lt;code&gt;sendSlack.gs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be careful not to disclose the Webhook URL to unauthorized persons.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function sendSlackMessage(body) {
  const SLACK_WEBHOOK_URL = "replace this";
  if (body.length === 0) {
    return;
  }

  const options = {
    headers: {
      "Content-Type": "application/json",
    },
    method: "post",
    payload: JSON.stringify({
      text: body,
    }),
  };

  try {
    UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options);
  } catch (error) {
    Logger.log("Error sending Slack message: " + error.toString());
  }
};

function createMessageBody(itemResponses) {
  let body = "Please check the following inquiry.";

  itemResponses.forEach(response =&amp;gt; {
    const question = response.getItem().getTitle();
    const answer = response.getResponse();
    body += "\n\n【" + question + "】\n\n" + answer;
  });

  return body;
}

function main(e) {
  const itemResponses = e.response.getItemResponses();
  const body = createMessageBody(itemResponses);
  sendSlackMessage(body);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfr9kgw9n3w8db3wro5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfr9kgw9n3w8db3wro5m.png" alt="Image description" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Google Apps Script Triggers
&lt;/h2&gt;

&lt;p&gt;Set up a trigger so that the process you just created is executed when a response is received in the Google Form. Select Triggers from the left nav, then click &lt;code&gt;Add Trigger&lt;/code&gt;. Set it up as follows and save.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kh8lnenpu0q0sj4fy85.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kh8lnenpu0q0sj4fy85.png" alt="Image description" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Function to execute: main&lt;/li&gt;
&lt;li&gt;Execute the deployment: Head&lt;/li&gt;
&lt;li&gt;Event source: Form&lt;/li&gt;
&lt;li&gt;Event type: On form submit&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;You are now ready. When you submit a response from the Google Form, a notification should arrive in the Slack channel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ychmqjbztzvc6uuumjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ychmqjbztzvc6uuumjr.png" alt="Image description" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Using Google Apps Script and Slack App allows direct integration without external tools. This reduces setup effort and makes customizing notifications and processing methods easier.&lt;/p&gt;

&lt;p&gt;Using ChatGPT to customize the processing is also recommended. I hope this article contributes to your life hacks.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>gas</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to use GPT-3 in Google Apps Script</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Tue, 24 Jan 2023 16:43:14 +0000</pubDate>
      <link>https://dev.to/tim_yone/how-to-use-gpt-3-in-google-apps-script-34if</link>
      <guid>https://dev.to/tim_yone/how-to-use-gpt-3-in-google-apps-script-34if</guid>
      <description>&lt;h1&gt;
  
  
  How to use GPT-3 in Google Apps Script
&lt;/h1&gt;

&lt;p&gt;GPT-3 (Generative Pre-trained Transformer 3) is a state-of-the-art language generation model developed by OpenAI. It has been trained on a diverse range of internet text and can generate human-like text on a wide range of topics.&lt;/p&gt;

&lt;p&gt;Why don't you use GPT-3 in Google Sheets? It's definitely useful if you could make it possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvjh3uvjlironx80jrykx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvjh3uvjlironx80jrykx.png" alt="Google Sheets and GPT-3" width="800" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I prepared two options to use GPT-3 with Google Sheets. You can follow the tutorial according to your purpose and skill set.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the sample sheet which has already deployed scripts.&lt;/li&gt;
&lt;li&gt;Create a new sheet and deploy scripts from your local development environment.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create your account at OpenAI
&lt;/h2&gt;

&lt;p&gt;You need to create an account at the first.&lt;br&gt;
&lt;a href="https://openai.com/api/" rel="noopener noreferrer"&gt;https://openai.com/api/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Access to OpenAI API keys, create a new secret key and copy it to your clipboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3k6qp7ssebtkb78pbkuu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3k6qp7ssebtkb78pbkuu.png" alt="OpenAI API keys" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Clone the sample sheet which has already deployed scripts
&lt;/h2&gt;

&lt;p&gt;You can clone &lt;a href="https://docs.google.com/spreadsheets/d/1xYZbBp4TFuSxOfjsW0HJtDCS3UEI5nWYd2FfPxEoLnQ/edit#gid=0" rel="noopener noreferrer"&gt;this sample sheet&lt;/a&gt; if you want to use GPT-3 function immediately without deployment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.google.com/spreadsheets/d/1xYZbBp4TFuSxOfjsW0HJtDCS3UEI5nWYd2FfPxEoLnQ/edit#gid=0" rel="noopener noreferrer"&gt;📈 gas-gpt3-sample&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: You need to set the OpenAI API key into script properties even though you cloned the sample sheet.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to set the OpenAI API key into script properties
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77fzbgaexonw04h8qulq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77fzbgaexonw04h8qulq.png" alt="Apps Script" width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your Apps Script project.&lt;/li&gt;
&lt;li&gt;At the left, click Project Settings The icon for project settings.&lt;/li&gt;
&lt;li&gt;To add the first property, under Script Properties click Add script property.&lt;/li&gt;
&lt;li&gt;To add second and subsequent properties, under Script Properties click Edit script properties &amp;gt; Add script property.&lt;/li&gt;
&lt;li&gt;For Property, enter the key name. The key name is must be &lt;code&gt;OPENAI_API_KEY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For Value, enter the secret key you generated before.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdel73wuy6tlz9k3h8l3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdel73wuy6tlz9k3h8l3s.png" alt="How to add script properties" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create a new sheet and deploy scripts from your local development environment
&lt;/h2&gt;

&lt;p&gt;Creating a repository from &lt;a href="https://github.com/Kazuki-tam/gas-gpt-starter" rel="noopener noreferrer"&gt;this template&lt;/a&gt; and cloning the repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/gas-gpt-starter" rel="noopener noreferrer"&gt;📖 gas-gpt-starter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You need to install Deno if you want to deploy and develop in your local environment.&lt;/p&gt;

&lt;p&gt;Deno v1.29.4 or higher&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deno.land/manual@v1.29.4/getting_started/installation" rel="noopener noreferrer"&gt;🦕 How to install Deno&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out how to use and follow the documentaion.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/gas-gpt-starter#how-to-use" rel="noopener noreferrer"&gt;📖 gas-gpt-starter: How to use&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. GPT-3 function
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Authorize this project's script by execution&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;GPT3()&lt;/code&gt; in your Google Workspace
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT3(prompt, maxTokens, model, temperature)

// Example 1 on Google Sheets
=GPT3("Hello, world!")

// Example 2 on Google Sheets
=GPT3(A1, 200)

// Example 3 on Google Sheets
=GPT3(A1, 300, "text-babbage-001", 0.5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;prompt: The prompt to generate completions for, encoded as a string, array of strings, array of tokens, or array of token arrays.&lt;/li&gt;
&lt;li&gt;maxTokens: The maximum number of tokens to generate in the completion.&lt;/li&gt;
&lt;li&gt;model: ID of the model to use.&lt;/li&gt;
&lt;li&gt;temperature: What sampling temperature to use. Higher values means the model will take more risks.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The combination between GPT-3 and Google Sheets is really useful. I hope this article will help you improve your productivity.&lt;/p&gt;

</description>
      <category>gpt3</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Sending ideas into Google Sheets by emoji reaction from Slack channel</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Sat, 22 Oct 2022 14:39:22 +0000</pubDate>
      <link>https://dev.to/tim_yone/sending-ideas-into-google-sheets-by-emoji-reaction-from-slack-channel-277</link>
      <guid>https://dev.to/tim_yone/sending-ideas-into-google-sheets-by-emoji-reaction-from-slack-channel-277</guid>
      <description>&lt;p&gt;Slack is one of the favorite messaging apps for businesses.&lt;br&gt;
It gives us a chatroom shared among all members of an organization.&lt;/p&gt;

&lt;p&gt;Have you ever wanted to save good ideas posted in Slack channel into Google Sheets?&lt;/p&gt;

&lt;p&gt;Zapier makes it possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://zapier.com/" rel="noopener noreferrer"&gt;📖 Learn more Zapier&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Sign up for Zapier
&lt;/h2&gt;

&lt;p&gt;Open this link and create your account.&lt;br&gt;
&lt;a href="https://zapier.com/sign-up" rel="noopener noreferrer"&gt;Zapier | sign up&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create a workflow
&lt;/h2&gt;

&lt;p&gt;You can use this workflow have been already set up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://zapier.com/apps/google-sheets/integrations/slack/237182/create-a-row-in-google-sheets-from-slack-messages-with-new-reactions" rel="noopener noreferrer"&gt;Create a row in Google Sheets from Slack messages with new reactions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connect Slack and Google Sheets by following the guide Zapier shows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuo9sp99vetbv2h0rqt0j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuo9sp99vetbv2h0rqt0j.png" alt="Zapier slack reaction" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a new sheet in Google Sheets when you see the bellow screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7p9irf30d2u5l7p8z3f7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7p9irf30d2u5l7p8z3f7.png" alt="Zapier Google sheets" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You need to add header items like this and delete rows after the second row.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Contributor&lt;/th&gt;
&lt;th&gt;Idea&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Message user name&lt;/td&gt;
&lt;td&gt;Message text&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbntu0jyufnn8c24racw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbntu0jyufnn8c24racw.png" alt="Google Sheets" width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set &lt;code&gt;Message user name&lt;/code&gt; and &lt;code&gt;Message text&lt;/code&gt; received from slack into the input fields of Zapier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovqlgjf9dmtuz9leh3j0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovqlgjf9dmtuz9leh3j0.png" alt="Zapier message fields" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Test workflow action
&lt;/h2&gt;

&lt;p&gt;Let's test your workflow action!&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Publish your workflow
&lt;/h2&gt;

&lt;p&gt;Publish your workflow after the workflow test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vkqqaayyyp55rhrtwu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vkqqaayyyp55rhrtwu5.png" alt="Zapier publish" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this tutorial will help your team to collect ideas and issues.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to run Whisper on Google Colaboratory</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Fri, 23 Sep 2022 13:11:59 +0000</pubDate>
      <link>https://dev.to/tim_yone/how-to-run-whisper-on-google-colaboratory-1ann</link>
      <guid>https://dev.to/tim_yone/how-to-run-whisper-on-google-colaboratory-1ann</guid>
      <description>&lt;p&gt;Whisper is a general-purpose speech recognition model open-sourced by OpenAI.&lt;/p&gt;

&lt;p&gt;According to the official article, the automatic speech recognition system is trained on 680,000 hours of multilingual and multitask supervised data collected from the web. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://openai.com/blog/whisper/" rel="noopener noreferrer"&gt;📖 Introducing Whisper&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was surprised by Whisper’s high accuracy and ease of use.&lt;br&gt;
Whisper provides so useful command line that you can feel free to try it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/openai/whisper#command-line-usage" rel="noopener noreferrer"&gt;📖 Command-line usage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll present how to run Whisper on Google Colaboratory here.&lt;br&gt;
You can refer to this Colab notebook if you want to try Whisper immediately on Google Colaboratory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://colab.research.google.com/gist/Kazuki-tam/04e85708e4fd1c4b8af180d317977f4d/whisper-mock-en.ipynb" rel="noopener noreferrer"&gt;📖 Colaboratory whisper-mock-en&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Create a new Colab notebook
&lt;/h2&gt;

&lt;p&gt;You need to crate a new Colab notebook from your Google Drive at the first.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hmf1jwdfk9zt481tr7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hmf1jwdfk9zt481tr7t.png" alt="Colab notebook" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You have to make sure your notebook is using a GPU. To do that, change a runtime type to GPU from the menu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8gfujd5rb8346rslaze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8gfujd5rb8346rslaze.png" alt="GPU from the menu" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Install package
&lt;/h2&gt;

&lt;p&gt;You need to install a package like the following line to run Whisper.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Install packages
&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;whisper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Add folders
&lt;/h2&gt;

&lt;p&gt;Add this code to create new folders when you click the play button.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="c1"&gt;# Add folders
&lt;/span&gt;&lt;span class="n"&gt;checkContentFolder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;checkDownLoadFolder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;download&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;checkContentFolder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;checkDownLoadFolder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;download&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Upload an audio file
&lt;/h2&gt;

&lt;p&gt;You have to upload at least an audio file into the &lt;code&gt;content&lt;/code&gt; folder after you've installed packages and added folders.&lt;/p&gt;
&lt;h2&gt;
  
  
  Transcription with Python
&lt;/h2&gt;

&lt;p&gt;You can modify the file name of the audio and target language to translate.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;whisper&lt;/span&gt;

&lt;span class="n"&gt;fileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sample.m4a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;whisper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Load audio
&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;whisper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_audio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;audio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;whisper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pad_or_trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;mel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;whisper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log_mel_spectrogram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Output the recognized text
&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;whisper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DecodingOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;without_timestamps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;whisper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Write into a text file
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;download/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;▼ Transcription of &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Download a transcription file
&lt;/h2&gt;

&lt;p&gt;It would be easy to download a transcription file if you added this code.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.colab&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;
&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;zip&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;zip&lt;/span&gt; &lt;span class="n"&gt;download&lt;/span&gt;
&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;download&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;download.zip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Let's run Whisper on Google Colaboratory
&lt;/h2&gt;

&lt;p&gt;Let's check how your code works on Colab notebook.&lt;br&gt;
I prepared a Colab notebook to use Whisper, so you can copy this notebook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://colab.research.google.com/gist/Kazuki-tam/04e85708e4fd1c4b8af180d317977f4d/whisper-mock-en.ipynb" rel="noopener noreferrer"&gt;📖 Colaboratory whisper-mock-en&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this tutorial got you to generate your first transcription.&lt;/p&gt;

</description>
      <category>python</category>
      <category>colab</category>
      <category>ai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Pure Liquid, a starter kit for static websites with Liquid template</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Sun, 18 Sep 2022 16:32:13 +0000</pubDate>
      <link>https://dev.to/tim_yone/pure-liquid-a-starter-kit-for-static-websites-and-jamstack-with-liquid-template-2bkk</link>
      <guid>https://dev.to/tim_yone/pure-liquid-a-starter-kit-for-static-websites-and-jamstack-with-liquid-template-2bkk</guid>
      <description>&lt;p&gt;There are a lot of template engines for static websites and dynamic websites. It takes time to learn a new template engine, especially for junior developers.&lt;/p&gt;

&lt;p&gt;I wanted to standardize using the same template engine picked from Pug, EJS, Liquid, and so on in the project team to solve the issue.&lt;/p&gt;

&lt;p&gt;It's been increased to build e-commerce sites with Shopify recently in my team. Shopify adopts Liquid as a template engine for theme development and introduces it to third-party developers.&lt;/p&gt;

&lt;p&gt;Liquid is a template language created by Shopify, but you actually can leverage it to develop other products than Shopify.&lt;/p&gt;

&lt;p&gt;For example, it might be more productive that you could develop a static website with Liquid if you usually build e-commerce sites with Shopify.&lt;/p&gt;

&lt;p&gt;I made a starter kit for static websites and Jamstack with the liquid template from the above point of view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pure Liquid
&lt;/h2&gt;

&lt;p&gt;The name of starter kit is "Pure Liquid".&lt;br&gt;
Pure Liquid enables you to develop a website more effectively than before if you are a theme developer for Shopify.&lt;br&gt;
You can also choose the Jamstack pattern in this kit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/pure-liquid#readme" rel="noopener noreferrer"&gt;💧 Pure Liquid&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Built-in static site generator&lt;/li&gt;
&lt;li&gt;Breaking HTML smaller files with Liquid&lt;/li&gt;
&lt;li&gt;HTML Validation with HTML-validate&lt;/li&gt;
&lt;li&gt;Lint TS files with ESLint&lt;/li&gt;
&lt;li&gt;Lint SCSS files with Stylelint&lt;/li&gt;
&lt;li&gt;Format code with prettier&lt;/li&gt;
&lt;li&gt;Compress images&lt;/li&gt;
&lt;li&gt;Creating SVG sprites&lt;/li&gt;
&lt;li&gt;Built-in test runner with Jest and Playwright&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;You need to follow these requirements below. I recommend you to use Yarn as a package manager.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node v16+&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://yarnpkg.com/" rel="noopener noreferrer"&gt;Yarn v2 (Recommendation)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Quick overview
&lt;/h2&gt;

&lt;p&gt;You can set up a static website by running one command.&lt;br&gt;
Please replace &lt;code&gt;&amp;lt;YOUR-PROJECT-NAME&amp;gt;&lt;/code&gt; with your own.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn create pure-liquid &amp;lt;YOUR-PROJECT-NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are ready to develop, so follow the below commands to start.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &amp;lt;YOUR-PROJECT-NAME&amp;gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; yarn build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see a default page when you access &lt;code&gt;http://localhost:8080&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5c3x3xd78xud6bl3b48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5c3x3xd78xud6bl3b48.png" alt="Image description" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you!
&lt;/h2&gt;

&lt;p&gt;I appreciate you for reading this article through to the end.&lt;br&gt;
I'll be trying to keep this starter kit as up-to-date as possible. Cheers!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>jamstack</category>
      <category>template</category>
    </item>
    <item>
      <title>How to make a reminder posts messages from Google Sheets to Slack</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Mon, 29 Aug 2022 09:15:00 +0000</pubDate>
      <link>https://dev.to/tim_yone/how-to-make-a-schedule-reminder-for-posting-messages-from-google-sheets-to-slack-2f11</link>
      <guid>https://dev.to/tim_yone/how-to-make-a-schedule-reminder-for-posting-messages-from-google-sheets-to-slack-2f11</guid>
      <description>&lt;p&gt;You sometimes would like to remind something from Google Sheets you usually manage if you are a heavy Google Sheets user.&lt;/p&gt;

&lt;p&gt;I'll introduce how to make a reminder that posts messages from Google Sheets to Slack.&lt;/p&gt;

&lt;p&gt;This video shows our goal in this tutorial.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/0N-3Wr9SmBU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;You need to follow the below prerequisite before you start this tutorial.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new sheet in Google sheets&lt;/li&gt;
&lt;li&gt;Create a workspace or join an existing workspace in Slack&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://github.com/Kazuki-tam/gas-sheets2slack" rel="noopener noreferrer"&gt;gas-sheets2slack&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Settings of Google Sheets
&lt;/h2&gt;

&lt;p&gt;Create a sheet to post messages to Slack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2du90tjoma2j2xnxyorl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2du90tjoma2j2xnxyorl.png" alt="Google Sheets" width="800" height="243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Notification&lt;/th&gt;
&lt;th&gt;Title&lt;/th&gt;
&lt;th&gt;Content&lt;/th&gt;
&lt;th&gt;Url&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2022/08/29&lt;/td&gt;
&lt;td&gt;Sample title&lt;/td&gt;
&lt;td&gt;This is a sample text.&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/"&gt;https://dev.to/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Open Apps Script from within Google Sheets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/apps-script/guides/sheets#get_started" rel="noopener noreferrer"&gt;📖 Lean more Extending Google Sheets&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get the script ID in Apps Script.&lt;br&gt;
⚠️ Save the ID to use it in development.&lt;/p&gt;
&lt;h2&gt;
  
  
  Settings of Slack apps
&lt;/h2&gt;

&lt;p&gt;Open &lt;a href="https://api.slack.com/apps" rel="noopener noreferrer"&gt;https://api.slack.com/apps&lt;/a&gt; and click “Create New App”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2uatfv28nzsdiarpvp6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2uatfv28nzsdiarpvp6p.png" alt="Image description" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select "From scratch".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls4jid0ubpja3fvqw4dk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fls4jid0ubpja3fvqw4dk.png" alt="Image description" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set up display information as you want.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gpw6im9w219zwh740jt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gpw6im9w219zwh740jt.png" alt="Image description" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In your left sidebar, navigate to "Incoming Webhooks" and then activate it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1jsl35mlv8darcn7asl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1jsl35mlv8darcn7asl.png" alt="Image description" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add new webhook to workspace and copy webhook URL.&lt;br&gt;
⚠️ Save the webhook URL to use it in development.&lt;/p&gt;
&lt;h2&gt;
  
  
  Google Apps Script
&lt;/h2&gt;

&lt;p&gt;We want to use Apps Script to post messages from Google Sheets regularly.&lt;/p&gt;

&lt;p&gt;I prepared a template for this project, so you don't have to spend extra time to develop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/gas-sheets2slack" rel="noopener noreferrer"&gt;👉 gas-sheets2slack&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Clone template
&lt;/h3&gt;

&lt;p&gt;Open the repository and click Use this template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11relt9q7lzw6zp0y8j7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11relt9q7lzw6zp0y8j7.png" alt="Image description" width="800" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clone the repository and install dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Login Google account
&lt;/h3&gt;

&lt;p&gt;Authorize management of your Google account's Apps Script projects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn clasp login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Create files
&lt;/h3&gt;

&lt;p&gt;Create a .clasp.json at the root, and then add these settings.&lt;br&gt;
Open App script from your spreadsheet and check out a script Id at the setting page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scriptId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;SCRIPT_ID&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rootDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a .env at the root, and then add "SLACK_WEBHOOK_URL".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SLACK_WEBHOOK_URL=&amp;lt;SLACK_WEBHOOK_URL&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Upload a script project
&lt;/h3&gt;

&lt;p&gt;Upload your script project's files from your local with this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click "Add trigger" from the trigger menu.&lt;br&gt;
Set up these options like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcewl2aahnfoyjakbioli.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcewl2aahnfoyjakbioli.png" alt="Image description" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apps Script finds out if the list has a notification date the same as today from your sheet every day.&lt;br&gt;
Apps Script posts a message when it finds out the date same as today.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run Apps Script
&lt;/h3&gt;

&lt;p&gt;Run "main.gs" in the editor menu and check out if you can receive a message in your slack channel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27rff5p0npmrmkc56d5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27rff5p0npmrmkc56d5z.png" alt="Image description" width="800" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this tutorial will help you to enhance your reminder flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/gas-sheets2slack" rel="noopener noreferrer"&gt;👉 gas-sheets2slack&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>gas</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Starter template for Shopify email notifications</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Thu, 11 Aug 2022 09:59:00 +0000</pubDate>
      <link>https://dev.to/tim_yone/starter-template-for-shopify-email-notifications-aod</link>
      <guid>https://dev.to/tim_yone/starter-template-for-shopify-email-notifications-aod</guid>
      <description>&lt;p&gt;Shopify provides you with default email templates that you can customize, so you don't need to make them from scratch.&lt;/p&gt;

&lt;p&gt;However, you sometimes would like to edit their content and design. You need to know the liquid template language created by Shopify and written in Ruby in that case.&lt;/p&gt;

&lt;p&gt;It's so hard to customize email templates in Liquid without any developmental environment at local that I've created a starter template that you can preview email templates at local.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/shopify-email-notification" rel="noopener noreferrer"&gt;🚀 shopify-email-notification&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/zgVnyliQKaU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Previewing notification mails at local server&lt;/li&gt;
&lt;li&gt;Hot reloading of local server&lt;/li&gt;
&lt;li&gt;Referring to default email templates which Shopify provides&lt;/li&gt;
&lt;li&gt;Based on Liquid templates&lt;/li&gt;
&lt;li&gt;Editable notification variables&lt;/li&gt;
&lt;li&gt;TypeScript support&lt;/li&gt;
&lt;li&gt;Multi language support (English and Japanese)&lt;/li&gt;
&lt;li&gt;Built in useful commands&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node v18 or higher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://shopify.dev/themes/tools/development-stores#create-a-development-store-for-a-client" rel="noopener noreferrer"&gt;Shopify store&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;p&gt;You can directly generate a new repository from this repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/shopify-email-notification" rel="noopener noreferrer"&gt;🚀 shopify-email-notification&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please click "Use this template".&lt;/p&gt;

&lt;h3&gt;
  
  
  Clone your project repository
&lt;/h3&gt;

&lt;p&gt;Clone the repository you generated from &lt;code&gt;shopify-email-notification&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install packages
&lt;/h3&gt;

&lt;p&gt;Install all dependencies for a project with bellow command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a &lt;code&gt;.env&lt;/code&gt; file (Optional)
&lt;/h3&gt;

&lt;p&gt;Create a .env at the root, and then add your shopify admin url. Replace your-shop-name with yours.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ADMIN_URL=https://your-shop-name.myshopify.com/admin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Start development
&lt;/h3&gt;

&lt;p&gt;Start your project in development mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;a href="http://localhost:4000" rel="noopener noreferrer"&gt;http://localhost:4000&lt;/a&gt;, and then you can preview notification templates.&lt;/p&gt;

&lt;p&gt;You can also open your store admin page with this command instantly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I recommend you use the format command because it notifies your syntax errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all to do before you start your project.&lt;/p&gt;

&lt;p&gt;I recommend you check out the command list before you get started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/shopify-email-notification#command-list" rel="noopener noreferrer"&gt;📖 Useful command list&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you!
&lt;/h2&gt;

&lt;p&gt;I hope that shopify-email-notification is helpful for you.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>shopify</category>
      <category>email</category>
      <category>node</category>
    </item>
    <item>
      <title>How to build a knowledge system with Slack and Notion</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Sat, 16 Apr 2022 10:53:10 +0000</pubDate>
      <link>https://dev.to/tim_yone/how-to-build-a-knowledge-system-with-slack-and-notion-52dc</link>
      <guid>https://dev.to/tim_yone/how-to-build-a-knowledge-system-with-slack-and-notion-52dc</guid>
      <description>&lt;p&gt;Have you ever felt like managing information flows more efficiently if you usually use Slack?&lt;/p&gt;

&lt;p&gt;I want to share tips to manage information by Slack and Notion in this article.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/TXE3GPRgjCs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Knowledge system by Slack and Notion
&lt;/h2&gt;

&lt;p&gt;You need to follow the below prerequisite before you start this tutorial.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slack paid plan&lt;/li&gt;
&lt;li&gt;Slack account&lt;/li&gt;
&lt;li&gt;Notion account&lt;/li&gt;
&lt;li&gt;Google account&lt;/li&gt;
&lt;li&gt;Google sheets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We actually need Google sheets to post messages to Notion from Slack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Settings of Notion
&lt;/h3&gt;

&lt;p&gt;Create a table to stock information. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Question: title&lt;/li&gt;
&lt;li&gt;Answer: rich_text&lt;/li&gt;
&lt;li&gt;URL: url&lt;/li&gt;
&lt;li&gt;Tags: multi_select&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0egar9qxa511td1ne5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0egar9qxa511td1ne5f.png" alt="Image description" width="800" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get a database's ID in Notion.&lt;br&gt;
&lt;a href="https://developers.notion.com/docs/working-with-databases" rel="noopener noreferrer"&gt;📖 Lean more Notion databases&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2w8aya39dsx95aez3y0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2w8aya39dsx95aez3y0g.png" alt="Image description" width="800" height="539"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;Copy link to view&lt;/code&gt; from the menu.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.notion.so/{workspace_name}/{database_id}?v={view_id}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ Save the ID to use it in development.&lt;/p&gt;

&lt;p&gt;In your left sidebar, navigate to Settings &amp;amp; Members and then the Integrations tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5uss7ce5764o9sfjdpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5uss7ce5764o9sfjdpn.png" alt="Image description" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click "Develop your own integrations".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohtk1249ypjf5zj7wkay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohtk1249ypjf5zj7wkay.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the + New integration button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw8qv2julfpya0yuvjcj9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw8qv2julfpya0yuvjcj9.png" alt="Image description" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setup settings of integration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fharcz194fpbuf8ix8tux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fharcz194fpbuf8ix8tux.png" alt="Image description" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the internal integration token.&lt;/p&gt;

&lt;p&gt;⚠️ Save the token to use it in development.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjh0gj4abmrw22n0jxdc0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjh0gj4abmrw22n0jxdc0.png" alt="Image description" width="793" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invite the integration which you created from the share menu.&lt;/p&gt;

&lt;h3&gt;
  
  
  Settings of Google Sheets
&lt;/h3&gt;

&lt;p&gt;Create a sheet to recieve messages from Slack and post them to Notion.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vm3zm2r8j38ru9cgvlf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vm3zm2r8j38ru9cgvlf.png" alt="Image description" width="800" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Answer&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;Tags&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;sample text&lt;/td&gt;
&lt;td&gt;sample text&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/"&gt;https://dev.to/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;sample, tags&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Open Apps Script from within Google Sheets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/apps-script/guides/sheets#get_started" rel="noopener noreferrer"&gt;📖 Lean more Extending Google Sheets&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get the script ID in Apps Script.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7sdy5q4bvzgji2tvv5nk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7sdy5q4bvzgji2tvv5nk.png" alt="Image description" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⚠️ Save the ID to use it in development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Settings of Slack
&lt;/h3&gt;

&lt;p&gt;We'll make an automation task with Workflow Builder in Slack.&lt;br&gt;
&lt;a href="https://slack.com/features/workflow-automation" rel="noopener noreferrer"&gt;📖 Lean more Workflow Builder&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkth2vqet745gvetihhbw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkth2vqet745gvetihhbw.png" alt="Image description" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a new workflow.&lt;/p&gt;
&lt;h3&gt;
  
  
  Workflow steps
&lt;/h3&gt;

&lt;p&gt;Follow this order and set up these settings.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Emoji reaction&lt;/li&gt;
&lt;li&gt;Send a form&lt;/li&gt;
&lt;li&gt;Add a spreadsheet row&lt;/li&gt;
&lt;li&gt;Send a message&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  1. Emoji reaction
&lt;/h4&gt;

&lt;p&gt;Choose "Emoji reaction" to start this workflow.&lt;br&gt;
Feel free to select it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykwdhimqgwjrh6fcy459.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykwdhimqgwjrh6fcy459.png" alt="Image description" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This workflow starts when someone adds the emoji reactions in the channel you've selected.&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Send a form
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6c2yn3aei8n87qkmvwz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6c2yn3aei8n87qkmvwz.png" alt="Image description" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select "Send a form" and add Questions like this below.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Question: Long answer&lt;/li&gt;
&lt;li&gt;Answer: Long answer&lt;/li&gt;
&lt;li&gt;URL: Short answer&lt;/li&gt;
&lt;li&gt;Tags: Short answer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixqhc8tomhf58y6rbs6o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixqhc8tomhf58y6rbs6o.png" alt="Image description" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make Question and Answer to be required.&lt;/p&gt;
&lt;h4&gt;
  
  
  3. Add a spreadsheet row
&lt;/h4&gt;

&lt;p&gt;We can use Google Sheets for Workflow Builder to save and manage messages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://slack.com/app-pages/google-sheets" rel="noopener noreferrer"&gt;📖 Lean more Google Sheets for Workflow Builder&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbpi6vv5b8a8eswzsi13u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbpi6vv5b8a8eswzsi13u.png" alt="Image description" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose "Add a spreadsheet row" from workflow options.&lt;/p&gt;
&lt;h4&gt;
  
  
  4. Send a message
&lt;/h4&gt;

&lt;p&gt;Create a message to respond to users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28utqi9cf4stlupuadnc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28utqi9cf4stlupuadnc.png" alt="Image description" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's test the workflow in your slack channel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpylwnhzncbcdnt1wlva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpylwnhzncbcdnt1wlva.png" alt="Image description" width="800" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, it's still not possible to post the message from Slack to Notion.&lt;/p&gt;
&lt;h3&gt;
  
  
  Deploy Google Apps Script
&lt;/h3&gt;

&lt;p&gt;We need to deploy Apps Script to post the message via Google Sheets from Slack to Notion.&lt;/p&gt;

&lt;p&gt;I prepared a template for this project, so you don't have to spend extra time to develop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/gas-slack2notion" rel="noopener noreferrer"&gt;https://github.com/Kazuki-tam/gas-slack2notion&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  1. Clone template
&lt;/h4&gt;

&lt;p&gt;Open the repository and click Use this template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11relt9q7lzw6zp0y8j7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11relt9q7lzw6zp0y8j7.png" alt="Image description" width="800" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clone the repository and install dependencies.&lt;/p&gt;

&lt;p&gt;Install &lt;a href="https://developers.google.com/apps-script/guides/clasp" rel="noopener noreferrer"&gt;Clasp&lt;/a&gt; at first if you haven't done it yet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @google/clasp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://developers.google.com/apps-script/guides/clasp" rel="noopener noreferrer"&gt;📖 Learn More Clasp&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  2. Login google account
&lt;/h4&gt;

&lt;p&gt;Authorize management of your Google account's Apps Script projects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx clasp login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Create files
&lt;/h4&gt;

&lt;p&gt;Create a .clasp.json at the root, and then add these settings.&lt;br&gt;
Open App script from your spreadsheet and check out a script Id at the setting page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scriptId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;SCRIPT_ID&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rootDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a .env at the root, and then add your token and database id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NOTION_TOKEN=&amp;lt;YOUR_NOTION_TOKEN&amp;gt;
DATABASE_ID=&amp;lt;YOUR_DATABASE_ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Upload a script project
&lt;/h4&gt;

&lt;p&gt;Upload your script project's files from your local with this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To set up an installable trigger, click on the Trigger menu.&lt;br&gt;
Click on it to add a trigger.&lt;/p&gt;

&lt;p&gt;Set up these options like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7wx8dnxaput47lyks3lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7wx8dnxaput47lyks3lg.png" alt="Image description" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Test workflow
&lt;/h3&gt;

&lt;p&gt;That's all you have to setup to create this project's workflow. Check if it works without problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It's really important to share your knowledge and experience in your team and company. I hope this tutorial will help you to enhance your knowledge system.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Starter kit for Shopify theme developers</title>
      <dc:creator>Kazuki Yonemoto</dc:creator>
      <pubDate>Mon, 07 Mar 2022 04:45:08 +0000</pubDate>
      <link>https://dev.to/tim_yone/starter-kit-for-shopify-theme-developers-5c5p</link>
      <guid>https://dev.to/tim_yone/starter-kit-for-shopify-theme-developers-5c5p</guid>
      <description>&lt;p&gt;I've created a starter kit for Shopify theme developers.&lt;br&gt;
You can customize a theme and build a new one from scratch efficiently.&lt;/p&gt;

&lt;p&gt;I've prepared two starter kits to develop the Shopify theme. I recommend you use &lt;code&gt;shopify-quick-theme-mix&lt;/code&gt; if you want to connect your Shopify store with the GitHub repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/shopify-quick-theme" rel="noopener noreferrer"&gt;🚀 shopify-quick-theme&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Kazuki-tam/shopify-quick-theme-mix" rel="noopener noreferrer"&gt;🚀 shopify-quick-theme-mix&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've always used Shopify Slate and Shopify Theme Kit to develop the Shopify theme.&lt;/p&gt;

&lt;p&gt;Shopify recommends using Shopify CLI at working on Online Store 2.0 especially. (2023/10)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://shopify.dev/docs/storefronts/themes/tools/cli" rel="noopener noreferrer"&gt;📖 Choosing between Shopify CLI and Theme Kit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These starter kits work on Shopify CLI fundamentally.&lt;/p&gt;
&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Node v22 or higher&lt;/li&gt;
&lt;li&gt;Shopify CLI v3 or higher&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please refer to &lt;a href="https://shopify.dev/themes/tools/cli/installation" rel="noopener noreferrer"&gt;Install Shopify CLI&lt;/a&gt; if you haven't installed Shopify CLI yet.&lt;/p&gt;
&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Abstracting Shopify CLI command&lt;/li&gt;
&lt;li&gt;Bundle files with Rspack&lt;/li&gt;
&lt;li&gt;Transpile SCSS to CSS&lt;/li&gt;
&lt;li&gt;Lint TS files with Biome&lt;/li&gt;
&lt;li&gt;Built-in test runner with Vitest and Playwright&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;p&gt;You can directly generate a new repository from this repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/shopify-quick-theme" rel="noopener noreferrer"&gt;🚀 shopify-quick-theme&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Kazuki-tam/shopify-quick-theme-mix" rel="noopener noreferrer"&gt;🚀 shopify-quick-theme-mix&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please click "Use this template".&lt;/p&gt;
&lt;h3&gt;
  
  
  Clone your project repository
&lt;/h3&gt;

&lt;p&gt;Clone the repository you generated from &lt;code&gt;shopify-quick-theme&lt;/code&gt; or &lt;code&gt;shopify-quick-theme-mix&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install packages
&lt;/h3&gt;

&lt;p&gt;Install all dependencies for a project with bellow command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a .env file
&lt;/h3&gt;

&lt;p&gt;Create a .env file at the root directory, and then add your SHOPIFY_FLAG_STORE value at least. Replace the placeholder YOUR_STORE_NAME with your actual store name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SHOPIFY_FLAG_STORE=YOUR_STORE_NAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a new theme
&lt;/h3&gt;

&lt;p&gt;Use newTheme command to create a new theme from scratch. This command creates a copy of Dawn.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm newTheme
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Customize an existing theme
&lt;/h3&gt;

&lt;p&gt;Use pull:new command to customize an existing theme.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm pull:new
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add CSS and JavaScript into your theme files
&lt;/h3&gt;

&lt;p&gt;Add these tags in &lt;code&gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&lt;/code&gt; section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'custom-style.css'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;asset_url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;stylesheet_tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&amp;lt;script src="&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'custom-script.js'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;asset_url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;" defer&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Start development
&lt;/h3&gt;

&lt;p&gt;Run a start command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GitHub integration
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/shopify-quick-theme" rel="noopener noreferrer"&gt;shopify-quick-theme&lt;/a&gt; doesn't support the Shopify GitHub integration because Shopify allows only branches that match the default Shopify theme folder structure. I recommend you to use git subtree or &lt;a href="https://github.com/Kazuki-tam/shopify-quick-theme-mix" rel="noopener noreferrer"&gt;shopify-quick-theme-mix&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kazuki-tam/shopify-quick-theme-mix" rel="noopener noreferrer"&gt;shopify-quick-theme-mix&lt;/a&gt; supports Shopify GitHub integration.&lt;/p&gt;

&lt;p&gt;That's all to do before you start your project🎉.&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
