diff --git a/.env.example b/.env.example
index 742b580..5166f7b 100644
--- a/.env.example
+++ b/.env.example
@@ -2,6 +2,5 @@ WEBSITE_ENV=
 WEBSITE_URL=
 MICROCMS_SERVICE_DOMAIN=
 MICROCMS_API_KEY=
-MICROCMS_WEBHOOK_KEY=
 CLOUDFLARE_ZONE_ID=
 CLOUDFLARE_API_KEY=
diff --git a/qlfile b/qlfile
index b4862b2..1b680f7 100644
--- a/qlfile
+++ b/qlfile
@@ -11,4 +11,3 @@ ql local-time
 ql function-cache
 ql jonathan
 ql access
-ql flexi-streams
diff --git a/qlfile.lock b/qlfile.lock
index 6421bac..f3d33ac 100644
--- a/qlfile.lock
+++ b/qlfile.lock
@@ -54,7 +54,3 @@
  (:class qlot/source/ql:source-ql
   :initargs (:%version :latest)
   :version "ql-2024-10-12"))
-("flexi-streams" .
- (:class qlot/source/ql:source-ql
-  :initargs (:%version :latest)
-  :version "ql-2024-10-12"))
diff --git a/src/components/header.lisp b/src/components/header.lisp
index 9546095..d4a2f9c 100644
--- a/src/components/header.lisp
+++ b/src/components/header.lisp
@@ -1,7 +1,6 @@
 (defpackage #:website/components/header
   (:use #:cl
-        #:hsx
-        #:jingle)
+        #:website/helper)
   (:export #:~header))
 (in-package #:website/components/header)
 
diff --git a/src/components/metadata.lisp b/src/components/metadata.lisp
index f8fb04a..780e2c8 100644
--- a/src/components/metadata.lisp
+++ b/src/components/metadata.lisp
@@ -1,7 +1,6 @@
 (defpackage #:website/components/metadata
   (:use #:cl
-        #:hsx
-        #:jingle)
+        #:website/helper)
   (:import-from #:website/lib/env
                 #:website-url)
   (:export #:~metadata))
diff --git a/src/helper.lisp b/src/helper.lisp
index c208395..a367676 100644
--- a/src/helper.lisp
+++ b/src/helper.lisp
@@ -1,26 +1,15 @@
 (uiop:define-package #:website/helper
-  (:use #:cl
-        #:jingle)
-  (:import-from #:flexi-streams
-                #:make-flexi-stream)
-  (:import-from #:jonathan
-                #:parse)
-  (:export #:api-request-p
-           #:get-request-body-plist))
+  (:use #:cl)
+  (:use-reexport #:hsx
+                 #:jingle
+                 #:jonathan
+                 #:access)
+  (:export #:api-p))
 (in-package #:website/helper)
 
 (defun starts-with-p (prefix string)
   (let ((pos (search prefix string :start1 0 :end1 (length prefix) :start2 0)))
     (and pos (= pos 0))))
 
-(defun api-request-p ()
+(defun api-p ()
   (starts-with-p "/api/" (request-uri *request*)))
-
-(defun get-request-body-plist ()
-  (parse
-   (let ((text-stream (make-flexi-stream (request-raw-body *request*)
-                                         :external-format :utf-8)))
-     (with-output-to-string (out)
-       (loop :for char := (read-char text-stream nil)
-             :while char
-             :do (write-char char out))))))
diff --git a/src/lib/cms.lisp b/src/lib/cms.lisp
index 7f75c80..7f24118 100644
--- a/src/lib/cms.lisp
+++ b/src/lib/cms.lisp
@@ -17,19 +17,21 @@
 (setf microcms:*service-domain* (microcms-service-domain))
 (setf microcms:*api-key* (microcms-api-key))
 
-(defmacro memorize (name)
+(defmacro memorize (name timeout)
   (let ((origin (gensym)))
     `(progn
        (setf (fdefinition ',origin) (fdefinition ',name))
-       (defcached ,name (&key query)
+       (defcached (,name :timeout ,timeout) (&key query)
          (,origin :query query)))))
 
+(defparameter *timeout* 60)
+
 (define-object-client about)
-(memorize get-about)
+(memorize get-about *timeout*)
 
 (define-object-client work)
-(memorize get-work)
+(memorize get-work *timeout*)
 
 (define-list-client blog)
-(memorize get-blog-list)
-(memorize get-blog-detail)
+(memorize get-blog-list *timeout*)
+(memorize get-blog-detail *timeout*)
diff --git a/src/lib/env.lisp b/src/lib/env.lisp
index f0a4bb1..a6e1ffb 100644
--- a/src/lib/env.lisp
+++ b/src/lib/env.lisp
@@ -18,4 +18,3 @@
 (env-var website-url "WEBSITE_URL")
 (env-var microcms-service-domain "MICROCMS_SERVICE_DOMAIN")
 (env-var microcms-api-key "MICROCMS_API_KEY")
-(env-var microcms-webhook-key "MICROCMS_WEBHOOK_KEY")
diff --git a/src/renderer.lisp b/src/renderer.lisp
index 7863e38..64c6724 100644
--- a/src/renderer.lisp
+++ b/src/renderer.lisp
@@ -1,11 +1,8 @@
 (defpackage #:website/renderer
   (:use #:cl
-        #:hsx
-        #:jingle)
-  (:import-from #:jonathan
-                #:to-json)
-  (:import-from #:website/helper
-                #:api-request-p)
+        #:website/helper)
+  (:import-from #:hsx/element
+                #:element)
   (:import-from #:website/components/metadata
                 #:~metadata)
   (:import-from #:website/components/scripts
@@ -17,7 +14,7 @@
 (defmethod jingle:process-response :around ((app jingle:app) result)
   (when (eq (request-method *request*) :get)
     (set-response-header :cache-control "public, max-age=60"))
-  (cond ((api-request-p)
+  (cond ((api-p)
          (set-response-header :content-type "application/json; charset=utf-8") 
          (call-next-method app (to-json result)))
         (t
diff --git a/src/routes/about.lisp b/src/routes/about.lisp
index 1fd330c..fa84d69 100644
--- a/src/routes/about.lisp
+++ b/src/routes/about.lisp
@@ -1,8 +1,6 @@
 (defpackage #:website/routes/about
   (:use #:cl
-        #:hsx
-        #:jingle
-        #:access)
+        #:website/helper)
   (:import-from #:website/lib/cms
                 #:get-about)
   (:import-from #:website/lib/time
diff --git a/src/routes/api/revalidate.lisp b/src/routes/api/revalidate.lisp
deleted file mode 100644
index 7c0457e..0000000
--- a/src/routes/api/revalidate.lisp
+++ /dev/null
@@ -1,24 +0,0 @@
-(defpackage #:website/routes/api/revalidate
-  (:use #:cl
-        #:jingle)
-  (:import-from #:function-cache
-                #:clear-cache)
-  (:import-from #:website/lib/env
-                #:microcms-webhook-key)
-  (:import-from #:website/helper
-                #:get-request-body-plist)
-  (:import-from #:website/lib/cms
-                #:get-about)
-  (:export #:handle-post))
-(in-package #:website/routes/api/revalidate)
-
-(defun handle-post (params)
-  (declare (ignore params))
-  (unless (string= (car (get-request-header "X-MICROCMS-WEBHOOK-KEY"))
-                   (microcms-webhook-key))
-    (set-response-status :unauthorized)
-    (return-from handle-post '(:|message| "Invalid token")))
-  (let* ((body (get-request-body-plist))
-         (api (getf body :|api|)))
-    (cond ((string= api "about") (clear-cache 'get-about)))
-    '(:|message| "ok")))
diff --git a/src/routes/blog.lisp b/src/routes/blog.lisp
index 820b359..051e7df 100644
--- a/src/routes/blog.lisp
+++ b/src/routes/blog.lisp
@@ -1,7 +1,6 @@
 (defpackage #:website/routes/blog
   (:use #:cl
-        #:hsx
-        #:jingle)
+        #:website/helper)
   (:export #:handle-get))
 (in-package #:website/routes/blog)
 
diff --git a/src/routes/index.lisp b/src/routes/index.lisp
index 398abbc..fe78adb 100644
--- a/src/routes/index.lisp
+++ b/src/routes/index.lisp
@@ -1,7 +1,6 @@
 (defpackage #:website/routes/index
   (:use #:cl
-        #:hsx
-        #:access)
+        #:website/helper)
   (:import-from #:website/lib/cms
                 #:get-about)
   (:export #:handle-get
diff --git a/src/routes/not-found.lisp b/src/routes/not-found.lisp
index 163ff70..b5ca783 100644
--- a/src/routes/not-found.lisp
+++ b/src/routes/not-found.lisp
@@ -1,9 +1,6 @@
 (defpackage #:website/routes/not-found
   (:use #:cl
-        #:hsx
-        #:jingle)
-  (:import-from #:website/helper
-                #:api-request-p)
+        #:website/helper)
   (:export #:handle-not-found))
 (in-package #:website/routes/not-found)
 
@@ -14,7 +11,7 @@
 
 (defun handle-not-found ()
   (setf (context :metadata) *metadata*)
-  (if (api-request-p)
+  (if (api-p)
       '(:|message| "404 Not Found")
       (hsx
        (div :class "flex flex-col h-full items-center justify-center gap-y-6"
diff --git a/src/routes/work.lisp b/src/routes/work.lisp
index c1e6cf4..97114cc 100644
--- a/src/routes/work.lisp
+++ b/src/routes/work.lisp
@@ -1,7 +1,6 @@
 (defpackage #:website/routes/work
   (:use #:cl
-        #:hsx
-        #:jingle)
+        #:website/helper)
   (:import-from #:website/lib/cms
                 #:get-work)
   (:import-from #:website/lib/time