diff --git a/packages/vue/src/composables/useSupported/index.test.ts b/packages/vue/src/composables/useSupported/index.test.ts
new file mode 100644
index 0000000..889a414
--- /dev/null
+++ b/packages/vue/src/composables/useSupported/index.test.ts
@@ -0,0 +1,37 @@
+import { defineComponent } from 'vue';
+import { describe, it, expect } from 'vitest';
+import { useSupported } from '.';
+import { mount } from '@vue/test-utils';
+
+const ComponentStub = defineComponent({
+ props: {
+ location: {
+ type: String,
+ default: 'location',
+ },
+ },
+ setup(props) {
+ const isSupported = useSupported(() => props.location in window);
+
+ return { isSupported };
+ },
+ template: `
{{ isSupported }}
`,
+});
+
+describe('useSupported', () => {
+ it('return whether the feature is supported', async () => {
+ const component = mount(ComponentStub);
+
+ expect(component.text()).toBe('true');
+ });
+
+ it('return whether the feature is not supported', async () => {
+ const component = mount(ComponentStub, {
+ props: {
+ location: 'unsupported',
+ },
+ });
+
+ expect(component.text()).toBe('false');
+ });
+});
\ No newline at end of file
diff --git a/packages/vue/src/composables/useSupported/index.ts b/packages/vue/src/composables/useSupported/index.ts
new file mode 100644
index 0000000..720778f
--- /dev/null
+++ b/packages/vue/src/composables/useSupported/index.ts
@@ -0,0 +1,27 @@
+import { computed } from 'vue';
+import { useMounted } from '../useMounted';
+
+/**
+ * @name useSupported
+ * @category Utilities
+ * @description SSR-friendly way to check if a feature is supported
+ *
+ * @param {Function} feature The feature to check for support
+ * @returns {ComputedRef} Whether the feature is supported
+ *
+ * @example
+ * const isSupported = useSupported(() => 'IntersectionObserver' in window);
+ *
+ * @example
+ * const isSupported = useSupported(() => 'ResizeObserver' in window);
+ */
+export function useSupported(feature: () => unknown) {
+ const isMounted = useMounted();
+
+ return computed(() => {
+ // add reactive dependency on isMounted
+ isMounted.value;
+
+ return Boolean(feature());
+ });
+}
\ No newline at end of file
diff --git a/packages/vue/tsconfig.json b/packages/vue/tsconfig.json
index d6d22e4..2d43941 100644
--- a/packages/vue/tsconfig.json
+++ b/packages/vue/tsconfig.json
@@ -1,3 +1,6 @@
{
- "extends": "@robonen/tsconfig/tsconfig.json"
+ "extends": "@robonen/tsconfig/tsconfig.json",
+ "compilerOptions": {
+ "lib": ["DOM"]
+ }
}
\ No newline at end of file